vitral 0.7.2 → 0.8.0

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 (59) hide show
  1. package/README.md +2 -0
  2. package/dist/angular.d.ts +2 -2
  3. package/dist/angular.js +8 -6
  4. package/dist/auto.js +5 -4
  5. package/dist/chunk-4IWZIFAL.js +165 -0
  6. package/dist/chunk-6AFVJCQG.js +311 -0
  7. package/dist/{chunk-72H4FXMD.js → chunk-6T25WKNK.js} +44 -13
  8. package/dist/chunk-EQZOJU3B.js +48 -0
  9. package/dist/{chunk-O7DV3EVB.js → chunk-NTXMEZIZ.js} +9 -46
  10. package/dist/{chunk-4NSPG6NK.js → chunk-PQXS2UDM.js} +1 -1
  11. package/dist/{chunk-TXSHK3SK.js → chunk-ZJ4IM2PZ.js} +2 -2
  12. package/dist/{chunk-V24ZNHUF.js → chunk-ZRAGLT3I.js} +4 -4
  13. package/dist/cli.js +1 -1
  14. package/dist/{contract-46EZFQPQ.js → contract-OMHCH6LI.js} +1 -1
  15. package/dist/{dedupe-S7BHQMOZ.js → dedupe-PZCSKL3L.js} +1 -1
  16. package/dist/edge.d.ts +1 -1
  17. package/dist/element.d.ts +2 -2
  18. package/dist/element.js +5 -4
  19. package/dist/embed.js +2 -2
  20. package/dist/{events-DLdbFqBM.d.ts → events-Cieg_far.d.ts} +1 -1
  21. package/dist/{expose-ZLYQZUP2.js → expose-V5ASGX4E.js} +2 -2
  22. package/dist/federation.d.ts +1 -1
  23. package/dist/{hydrate-NFZZMYWT.js → hydrate-6NE4MYOD.js} +7 -5
  24. package/dist/iframe.js +9 -7
  25. package/dist/index.d.ts +6 -19
  26. package/dist/index.js +6 -4
  27. package/dist/loader-BIXjuvvp.d.ts +25 -0
  28. package/dist/next-config.d.ts +95 -0
  29. package/dist/next-config.js +149 -0
  30. package/dist/next-host.d.ts +26 -0
  31. package/dist/next-host.js +92 -0
  32. package/dist/next.d.ts +190 -0
  33. package/dist/next.js +287 -0
  34. package/dist/preact.d.ts +4 -4
  35. package/dist/preact.js +7 -5
  36. package/dist/prefetch.js +2 -2
  37. package/dist/react-server.d.ts +1 -1
  38. package/dist/react.d.ts +11 -4
  39. package/dist/react.js +17 -144
  40. package/dist/{reframe-7K5S6JC6.js → reframe-3ZN5CHEG.js} +4 -4
  41. package/dist/routes.d.ts +2 -2
  42. package/dist/routes.js +6 -4
  43. package/dist/single-spa.d.ts +1 -1
  44. package/dist/{slot-Ddzp7AgL.d.ts → slot-Dhczjs1E.d.ts} +1 -1
  45. package/dist/solid.d.ts +3 -3
  46. package/dist/solid.js +7 -5
  47. package/dist/{sri-576GTDIA.js → sri-TBZ6PYYY.js} +39 -24
  48. package/dist/svelte.d.ts +4 -4
  49. package/dist/svelte.js +6 -4
  50. package/dist/sw.d.ts +8 -0
  51. package/dist/sw.js +21 -0
  52. package/dist/testing.d.ts +1 -1
  53. package/dist/testing.js +3 -2
  54. package/dist/{types-EOz1rOHs.d.ts → types-wsKR1gfx.d.ts} +19 -3
  55. package/dist/vite.d.ts +33 -1
  56. package/dist/vite.js +353 -158
  57. package/dist/vue.d.ts +3 -3
  58. package/dist/vue.js +6 -4
  59. package/package.json +28 -12
package/dist/vite.js CHANGED
@@ -1,3 +1,9 @@
1
+ import {
2
+ BOOT,
3
+ dedupeHooks,
4
+ dedupeIds,
5
+ groups
6
+ } from "./chunk-6AFVJCQG.js";
1
7
  import {
2
8
  extractProps,
3
9
  typesFile
@@ -5,8 +11,9 @@ import {
5
11
 
6
12
  // src/vite.ts
7
13
  import { createHash as createHash3 } from "crypto";
8
- import { readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
9
- import { join as join4, resolve as resolve4 } from "path";
14
+ import { createRequire as createRequire3 } from "module";
15
+ import { readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
16
+ import { join as join5, resolve as resolve4 } from "path";
10
17
 
11
18
  // src/vite-exposes.ts
12
19
  import { resolve } from "path";
@@ -37,9 +44,13 @@ import { createHash } from "crypto";
37
44
  import { readFileSync, rmSync, writeFileSync } from "fs";
38
45
  import { join, posix } from "path";
39
46
  var SPLIT = "split/";
47
+ var PROBES = [
48
+ [`${SPLIT}vitral-probe.js`, "export{}"],
49
+ [`${SPLIT}vitral-probe-x.js`, "export{}//"]
50
+ ];
40
51
  var sri = (file) => "sha384-" + createHash("sha384").update(readFileSync(file)).digest("base64");
41
52
  function outputs(rolldown, hints = false) {
42
- const banner = hints ? { banner: compileHint } : {};
53
+ const banner = hints ? { [rolldown ? "postBanner" : "banner"]: compileHint } : {};
43
54
  return [
44
55
  { format: "es", ...banner, ...rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
45
56
  // Os assets saem com o mesmo nome nas duas (o Vite só aceita um padrão).
@@ -75,7 +86,15 @@ function collect(outDir, bundle) {
75
86
  for (const d of live.get(entry)) if (!Object.values(own).some((o) => o.file === d)) soon.add(d), deps(d, soon);
76
87
  }
77
88
  soon.delete(entry);
78
- return { entry, chunks: [...soon], files: [...used], own };
89
+ const ownFiles = new Set(Object.values(own).map((o) => o.file));
90
+ const app = /* @__PURE__ */ new Set();
91
+ const stack = [entry];
92
+ while (stack.length) {
93
+ const n = stack.pop();
94
+ for (const d of [...byName.get(n)?.imports ?? [], ...live.get(n)]) if (byName.has(d) && !ownFiles.has(d) && !app.has(d)) app.add(d), stack.push(d);
95
+ }
96
+ const lazy = [...app].filter((n) => n !== entry && !soon.has(n));
97
+ return { entry, chunks: [...soon], files: [...used], own, lazy };
79
98
  }
80
99
  function rewrite(file, c, byName, deps) {
81
100
  const targets = c.dynamicImports.filter((d) => byName.has(d));
@@ -109,7 +128,8 @@ function withSplit(m, outDir, s, groups2 = []) {
109
128
  const files = {};
110
129
  for (const f of [m.entry, ...m.css ?? [], ...m.shadow?.css ?? [], ...m.shadow?.global ?? [], ...s?.files ?? []]) files[f] = sri(join(outDir, f));
111
130
  const dedupe = groups2.filter((g) => s?.own[g.name]).map(({ name, range, version }) => ({ name, range, version, ...s.own[name] }));
112
- return { ...m, files, ...s && { split: { entry: s.entry, chunks: s.chunks } }, ...dedupe.length && { dedupe } };
131
+ if (s) for (const [file, code] of PROBES) writeFileSync(join(outDir, file), code);
132
+ return { ...m, files, ...s && { split: { entry: s.entry, chunks: s.chunks, ...s.lazy.length && { lazy: s.lazy } }, probe: PROBES.map(([f]) => f) }, ...dedupe.length && { dedupe } };
113
133
  }
114
134
 
115
135
  // src/vite/sbom.ts
@@ -252,114 +272,6 @@ function createSbom(input) {
252
272
  };
253
273
  }
254
274
 
255
- // src/vite/dedupe.ts
256
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
257
- import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
258
- import { pathToFileURL } from "url";
259
- var REACT = ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "react/jsx-dev-runtime", "react/compiler-runtime"];
260
- var BOOT = "virtual:vitral-boot";
261
- var DEPS = "\0vitral-deps";
262
- var OWN = "\0vitral-own:";
263
- var SHIM = "\0vitral-shim:";
264
- var pkgOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
265
- var groupOf = (spec) => REACT.includes(spec) || pkgOf(spec) === "scheduler" ? "react" : pkgOf(spec);
266
- var ident = /^[A-Za-z_$][\w$]*$/;
267
- function versionOf(file, pkg) {
268
- for (let dir = dirname2(file); dir !== dirname2(dir); dir = dirname2(dir)) {
269
- const json = join3(dir, "package.json");
270
- if (!existsSync2(json)) continue;
271
- const data = JSON.parse(readFileSync3(json, "utf8"));
272
- if (data.name === pkg) return data.version;
273
- }
274
- throw new Error(`vitral: vers\xE3o de ${pkg} n\xE3o encontrada`);
275
- }
276
- async function groups(list, root, entry, resolveId) {
277
- const importer = resolve2(root, entry);
278
- const byName = /* @__PURE__ */ new Map();
279
- for (const spec of list) {
280
- const g = groupOf(spec);
281
- byName.set(g, [.../* @__PURE__ */ new Set([...byName.get(g) ?? [], ...g === "react" ? REACT : [spec]])]);
282
- }
283
- const out = [];
284
- for (const [name, specs] of byName) {
285
- const group = { name, range: "", version: "", keys: [], names: {}, pkgs: name === "react" ? ["react", "react-dom", "scheduler"] : [name] };
286
- for (const spec of specs) {
287
- const found = await resolveId(spec, importer);
288
- if (!found) {
289
- if (spec === name) throw new Error(`vitral: dedupe: ${spec} n\xE3o est\xE1 instalado`);
290
- continue;
291
- }
292
- const mod = await import(pathToFileURL(found.id.split("?")[0]).href);
293
- const extra = mod.default && typeof mod.default === "object" ? Object.keys(mod.default) : [];
294
- group.names[spec] = [.../* @__PURE__ */ new Set([...Object.keys(mod), ...extra])].filter((n) => n !== "default" && ident.test(n));
295
- group.keys.push(spec);
296
- if (spec === name) group.version = versionOf(found.id, name);
297
- }
298
- group.range = name === "svelte" || name.startsWith("@angular/") ? group.version : `^${group.version}`;
299
- out.push(group);
300
- }
301
- return out;
302
- }
303
- var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\0/g, "\\x00");
304
- function dedupeIds(list) {
305
- const specs = new Set(list.flatMap((s) => groupOf(s) === "react" ? REACT : [s]));
306
- return new RegExp(`${escape(BOOT)}$|^(${[DEPS, ...specs].map(escape).join("|")})$|^(${escape(OWN)}|${escape(SHIM)})`);
307
- }
308
- function dedupeHooks(entry, getGroups) {
309
- const keyOf = (id) => getGroups().find((g) => g.keys.includes(id));
310
- return {
311
- resolveId: {
312
- order: "pre",
313
- handler(id, importer) {
314
- if (id.endsWith(BOOT)) return `\0${BOOT}`;
315
- if (id === DEPS || id.startsWith(OWN) || id.startsWith(SHIM)) return id;
316
- const g = keyOf(id);
317
- if (!g || !importer || importer.startsWith(OWN)) return null;
318
- const norm = importer.replace(/\\/g, "/");
319
- if (g.pkgs.some((p) => norm.includes(`/node_modules/${p}/`))) return null;
320
- return SHIM + id;
321
- }
322
- },
323
- load(id) {
324
- if (id === `\0${BOOT}`) return boot(entry(), getGroups());
325
- if (id === DEPS) return "export const deps = {}";
326
- if (id.startsWith(OWN)) {
327
- const g = getGroups().find((x) => x.name === id.slice(OWN.length));
328
- return g.keys.map((k, i) => `import * as m${i} from ${JSON.stringify(k)}`).join("\n") + `
329
- export default {${g.keys.map((k, i) => `${JSON.stringify(k)}: m${i}`).join(", ")}}
330
- `;
331
- }
332
- if (id.startsWith(SHIM)) {
333
- const spec = id.slice(SHIM.length);
334
- const names = keyOf(spec).names[spec];
335
- return `import { deps } from ${JSON.stringify(DEPS)}
336
- const m = deps[${JSON.stringify(spec)}]
337
- export default m.default ?? m
338
- ` + (names.length ? `export const { ${names.join(", ")} } = m
339
- ` : "");
340
- }
341
- return null;
342
- }
343
- };
344
- }
345
- function boot(entry, groups2) {
346
- const calls = groups2.map(
347
- (g) => `need(${JSON.stringify(g.name)}, ${JSON.stringify(g.range)}, ${JSON.stringify(g.version)}, ${JSON.stringify(g.keys)}, () => import(${JSON.stringify(OWN + g.name)}).then((m) => m.default))`
348
- );
349
- return `const { deps } = await import(${JSON.stringify(DEPS)})
350
- const p = globalThis[Symbol.for("vitral")]
351
- const shared = !!(p && p.dedupe) && /\\/split\\/[^/]*$/.test(import.meta.url)
352
- async function need(name, range, version, keys, load) {
353
- let m = shared && (await p.dedupe(name, range, { version, load }))
354
- if (!m || keys.some((k) => !(k in m))) m = await load()
355
- Object.assign(deps, m)
356
- }
357
- await Promise.all([${calls.join(", ")}])
358
- const remote = await import(${JSON.stringify(entry)})
359
- export default remote.default
360
- `;
361
- }
362
-
363
275
  // src/css-build.ts
364
276
  import postcss2 from "postcss";
365
277
 
@@ -564,8 +476,8 @@ function splitShadowCss(text) {
564
476
  }
565
477
 
566
478
  // src/vite/adapter.ts
567
- import { existsSync as existsSync3 } from "fs";
568
- import { resolve as resolve3 } from "path";
479
+ import { existsSync as existsSync2 } from "fs";
480
+ import { resolve as resolve2 } from "path";
569
481
  var PLUGINS = [
570
482
  [/^(preact:|prefresh$)/, "preact"],
571
483
  [/^vite:react/, "react"],
@@ -588,14 +500,17 @@ var WRAP = {
588
500
  };
589
501
  var ENTRY_ID = "__vitral_entry__.js";
590
502
  var VIRTUAL_ENTRY = "\0vitral:entry";
591
- function entryCode(file, adapter, scope) {
503
+ function entryCode(file, adapter, scope, next = false) {
592
504
  const head = `import * as m from ${JSON.stringify(file)}
593
505
  const c = m.default ?? m
594
506
  `;
595
507
  if (adapter !== "element") {
596
508
  const [from, fn] = WRAP[adapter];
597
- return `${head}import { ${fn} as wrap } from '${from}'
598
- export default typeof c?.mount === 'function' ? c : wrap(c)
509
+ const inner = next && adapter === "react" ? "nextRemote(c)" : "c";
510
+ const bridge = inner === "c" ? "" : `import { nextRemote } from 'vitral/next'
511
+ `;
512
+ return `${head}${bridge}import { ${fn} as wrap } from '${from}'
513
+ export default typeof c?.mount === 'function' ? c : wrap(${inner})
599
514
  `;
600
515
  }
601
516
  return `${head}import { elementRemote } from 'vitral/element'
@@ -622,7 +537,7 @@ var CANDIDATES = ["src/remote", "src/App", "src/app"];
622
537
  var EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".vue", ".svelte"];
623
538
  function findEntry(root) {
624
539
  for (const base of CANDIDATES) {
625
- for (const ext of EXTENSIONS) if (existsSync3(resolve3(root, base + ext))) return base + ext;
540
+ for (const ext of EXTENSIONS) if (existsSync2(resolve2(root, base + ext))) return base + ext;
626
541
  }
627
542
  }
628
543
 
@@ -736,6 +651,209 @@ function mcpAppHtml(page) {
736
651
  `;
737
652
  }
738
653
 
654
+ // src/vite/minify.ts
655
+ var HINT = "//# allFunctionsCalledOnLoad";
656
+ async function minifyWhitespace(code, file, sourcemap) {
657
+ const vite = await import("vite");
658
+ const hint = code.startsWith(HINT);
659
+ if (typeof vite.transformWithEsbuild !== "function") return null;
660
+ const out = await vite.transformWithEsbuild(code, file, { minifyWhitespace: true, legalComments: "none", format: "esm", loader: "js", sourcemap });
661
+ if (!hint || out.code.startsWith(HINT)) return { code: out.code, map: out.map };
662
+ const map = out.map && typeof out.map === "object" ? { ...out.map, mappings: ";" + out.map.mappings } : out.map;
663
+ return { code: `${HINT}
664
+ ${out.code}`, map };
665
+ }
666
+
667
+ // src/vite/next.ts
668
+ var MODULES = {
669
+ "next/link": 'export { Link as default } from "vitral/next"',
670
+ "next/image": 'export { Image as default } from "vitral/next"',
671
+ "next/head": 'export { Head as default } from "vitral/next"',
672
+ "next/dynamic": 'export { dynamic as default } from "vitral/next"',
673
+ "next/router": 'export { useRouter, withRouter, Router as default } from "vitral/next"',
674
+ "next/navigation": 'export { useAppRouter as useRouter, usePathname, useSearchParams, useParams, redirect, notFound } from "vitral/next"',
675
+ "next/dist/shared/lib/router-context.shared-runtime": 'export { RouterContext } from "vitral/next"'
676
+ };
677
+ var NEXT_IDS = /^next\/(link|image|head|dynamic|router|navigation|dist\/shared\/lib\/router-context\.shared-runtime)(\.js)?$/;
678
+ var PREFIX = "\0vitral-next:";
679
+ function resolveNextId(id) {
680
+ const name = id.replace(/\.js$/, "");
681
+ return MODULES[name] ? PREFIX + name : void 0;
682
+ }
683
+ function loadNext(id, options) {
684
+ if (!id.startsWith(PREFIX)) return;
685
+ const code = MODULES[id.slice(PREFIX.length)];
686
+ return code && `import { setBasePath } from "vitral/next"
687
+ setBasePath(${JSON.stringify(options.basePath ?? "")})
688
+ ${code}
689
+ `;
690
+ }
691
+ function nextDefine(env, mode) {
692
+ const vars = { NODE_ENV: mode === "development" ? "development" : "production" };
693
+ for (const [k, v] of Object.entries(env)) if (k.startsWith("NEXT_PUBLIC_")) vars[k] = v;
694
+ return {
695
+ "process.env": JSON.stringify(vars),
696
+ ...Object.fromEntries(Object.entries(vars).map(([k, v]) => [`process.env.${k}`, JSON.stringify(v)]))
697
+ };
698
+ }
699
+
700
+ // src/vite/tsconfig.ts
701
+ import { existsSync as existsSync3, readFileSync as readFileSync3, statSync } from "fs";
702
+ import { createRequire } from "module";
703
+ import { dirname as dirname2, join as join3, resolve as resolve3 } from "path";
704
+ function parseJsonc(text) {
705
+ let out = "";
706
+ for (let i = 0; i < text.length; i++) {
707
+ const c = text[i];
708
+ if (c === '"') {
709
+ const end = /"(?:[^"\\]|\\.)*"/y;
710
+ end.lastIndex = i;
711
+ const m = end.exec(text);
712
+ const s = m ? m[0] : text.slice(i);
713
+ out += s;
714
+ i += s.length - 1;
715
+ } else if (c === "/" && text[i + 1] === "/") {
716
+ while (i < text.length && text[i] !== "\n") i++;
717
+ out += "\n";
718
+ } else if (c === "/" && text[i + 1] === "*") {
719
+ i = text.indexOf("*/", i + 2);
720
+ if (i < 0) break;
721
+ i++;
722
+ } else out += c;
723
+ }
724
+ return JSON.parse(out.replace(/,(\s*[}\]])/g, "$1"));
725
+ }
726
+ function read(file, seen = /* @__PURE__ */ new Set()) {
727
+ if (seen.has(file)) return {};
728
+ seen.add(file);
729
+ const json = parseJsonc(readFileSync3(file, "utf8"));
730
+ const dir = dirname2(file);
731
+ let inherited = {};
732
+ for (const ext of [json.extends ?? []].flat()) {
733
+ try {
734
+ const from = ext.startsWith(".") ? resolve3(dir, ext) : createRequire(file).resolve(ext);
735
+ inherited = { ...inherited, ...read(existsSync3(from) ? from : from + ".json", seen) };
736
+ } catch {
737
+ }
738
+ }
739
+ const o = json.compilerOptions ?? {};
740
+ const baseUrl = o.baseUrl != null ? resolve3(dir, o.baseUrl) : inherited.baseUrl;
741
+ return {
742
+ baseUrl,
743
+ paths: o.paths ?? inherited.paths,
744
+ // Sem baseUrl, os alvos de `paths` são relativos ao tsconfig que os declara.
745
+ pathsBase: o.paths ? o.baseUrl != null ? baseUrl : dir : inherited.pathsBase
746
+ };
747
+ }
748
+ var cache = /* @__PURE__ */ new Map();
749
+ function pathsFor(file) {
750
+ const c = tsconfigFor(dirname2(file));
751
+ const n = (p) => p.replace(/\\/g, "/");
752
+ return c && n(file).includes("/node_modules/") && !n(c.dir).includes("/node_modules/") ? null : c;
753
+ }
754
+ function tsconfigFor(dir) {
755
+ if (cache.has(dir)) return cache.get(dir);
756
+ const file = join3(dir, "tsconfig.json");
757
+ let found;
758
+ if (existsSync3(file)) {
759
+ try {
760
+ const c = read(file);
761
+ found = c.paths ? { dir, base: c.pathsBase ?? dir, paths: c.paths } : null;
762
+ } catch {
763
+ found = null;
764
+ }
765
+ } else found = dirname2(dir) === dir ? null : tsconfigFor(dirname2(dir));
766
+ cache.set(dir, found);
767
+ return found;
768
+ }
769
+ function pathCandidates(id, c) {
770
+ let best;
771
+ for (const [key, targets] of Object.entries(c.paths)) {
772
+ const star = key.indexOf("*");
773
+ if (star < 0 ? id !== key : !(id.startsWith(key.slice(0, star)) && id.endsWith(key.slice(star + 1)) && id.length >= key.length - 1)) continue;
774
+ const size = star < 0 ? Infinity : star;
775
+ if (!best || size > best.size) best = { targets, rest: star < 0 ? "" : id.slice(star, id.length - (key.length - star - 1)), size };
776
+ }
777
+ if (!best) return;
778
+ const out = best.targets.map((t) => {
779
+ const path = resolve3(c.base, t.replace("*", best.rest));
780
+ return path.replace(/\\/g, "/").endsWith(`/node_modules/${id}`) ? id : path;
781
+ });
782
+ return out.every((t) => t === id) ? void 0 : out;
783
+ }
784
+ var EXTENSIONS2 = ["", ".ts", ".tsx", ".mts", ".js", ".jsx", ".mjs", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
785
+ function fileOf(path) {
786
+ for (const ext of EXTENSIONS2) {
787
+ try {
788
+ if (statSync(path + ext).isFile()) return path + ext;
789
+ } catch {
790
+ }
791
+ }
792
+ }
793
+ function resolvePath(id, importer) {
794
+ const config = pathsFor(importer);
795
+ const candidates = config && pathCandidates(id, config);
796
+ for (const c of candidates ?? []) {
797
+ if (c === id) return;
798
+ const file = fileOf(c);
799
+ if (file) return file;
800
+ }
801
+ }
802
+ function optimizerPaths(rolldown) {
803
+ if (rolldown)
804
+ return {
805
+ rolldownOptions: {
806
+ plugins: [{ name: "vitral:paths", resolveId: (id, importer) => importer && !/^[./\0]/.test(id) ? resolvePath(id, importer) : void 0 }]
807
+ }
808
+ };
809
+ return {
810
+ esbuildOptions: {
811
+ plugins: [
812
+ {
813
+ name: "vitral:paths",
814
+ setup(build) {
815
+ build.onResolve({ filter: /^[^./]/ }, (args) => {
816
+ const file = args.importer && resolvePath(args.path, args.importer);
817
+ return file ? { path: file } : void 0;
818
+ });
819
+ }
820
+ }
821
+ ]
822
+ }
823
+ };
824
+ }
825
+
826
+ // src/vite/svg.ts
827
+ import { readFileSync as readFileSync4 } from "fs";
828
+ import { createRequire as createRequire2 } from "module";
829
+ import { basename, join as join4 } from "path";
830
+ import { pathToFileURL } from "url";
831
+ async function svgComponents(root) {
832
+ const req = createRequire2(join4(root, "package.json"));
833
+ const load = async (id) => import(pathToFileURL(req.resolve(id)).href).then((m) => m.default ?? m);
834
+ let svgr;
835
+ let plugins;
836
+ try {
837
+ svgr = (await load("@svgr/core")).transform;
838
+ plugins = [await load("@svgr/plugin-jsx")];
839
+ } catch {
840
+ return;
841
+ }
842
+ try {
843
+ plugins.unshift(await load("@svgr/plugin-svgo"));
844
+ } catch {
845
+ }
846
+ const vite = await import("vite");
847
+ return {
848
+ async transform(file) {
849
+ const name = basename(file, ".svg").replace(/(^|[^a-zA-Z0-9])([a-zA-Z0-9])/g, (_, _s, c) => c.toUpperCase());
850
+ const jsx = await svgr(readFileSync4(file, "utf8"), { plugins, jsxRuntime: "automatic" }, { filePath: file, componentName: `Svg${name}` });
851
+ const out = vite.transformWithOxc ? await vite.transformWithOxc(jsx, file + ".jsx", { lang: "jsx", jsx: { runtime: "automatic" } }) : await vite.transformWithEsbuild(jsx, file + ".jsx", { loader: "jsx", jsx: "automatic" });
852
+ return { code: out.code, map: null };
853
+ }
854
+ };
855
+ }
856
+
739
857
  // src/vite/dev.ts
740
858
  var DEV_ENTRY = "@vitral/entry.js";
741
859
  var VIRTUAL_DEV_ENTRY = "\0vitral:dev-entry";
@@ -839,19 +957,25 @@ function vitral(options = {}) {
839
957
  let framework = "element";
840
958
  const entryFile = () => resolve4(root, entry);
841
959
  let serve = false;
960
+ let minify = false;
961
+ let rolldown = false;
842
962
  let shared = [];
963
+ let svg;
843
964
  const dedupe = !!options.dedupe?.length;
844
965
  const hooks = dedupeHooks(() => options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entryFile() : ENTRY_ID, () => shared);
845
966
  const mcp = options.target === "mcp-app";
967
+ const next = options.next === true ? {} : options.next || void 0;
968
+ const paths = !!next && next.tsconfigPaths !== false;
969
+ const files = !!options.dedupe?.some((d) => d.endsWith("/*"));
846
970
  if (mcp && (options.exposes || dedupe || options.shared?.length)) {
847
971
  throw new Error("[vitral] target: 'mcp-app' gera um HTML \xFAnico: n\xE3o combina com exposes, dedupe nem shared.");
848
972
  }
849
973
  const scopeName = () => (options.name ?? pkg.name ?? "remote").replace(/[^a-zA-Z0-9_-]/g, "-");
850
- const mcpApp = (files, js) => {
851
- const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => f.fileName);
852
- const read = (file) => {
853
- const text = readFileSync4(join4(outDir, file), "utf8");
854
- rmSync2(join4(outDir, file));
974
+ const mcpApp = (files2, js) => {
975
+ const css = files2.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => f.fileName);
976
+ const read2 = (file) => {
977
+ const text = readFileSync5(join5(outDir, file), "utf8");
978
+ rmSync2(join5(outDir, file));
855
979
  return text;
856
980
  };
857
981
  const scope = options.scopeCss === false ? void 0 : scopeName();
@@ -859,27 +983,28 @@ function vitral(options = {}) {
859
983
  name: options.name ?? pkg.name ?? "remote",
860
984
  version: options.version ?? pkg.version,
861
985
  scope,
862
- code: read(js),
863
- css: css.map((f) => transformCss(read(f), options, scopeName()))
986
+ code: read2(js),
987
+ css: css.map((f) => transformCss(read2(f), options, scopeName()))
864
988
  });
865
- writeFileSync2(join4(outDir, "mcp-app.html"), html);
989
+ writeFileSync2(join5(outDir, "mcp-app.html"), html);
866
990
  };
867
991
  return {
868
992
  name: "vitral",
869
- config(user, { mode, command }) {
993
+ async config(user, { mode, command }) {
870
994
  entry ??= findEntry(resolve4(user.root ?? process.cwd()));
871
995
  if (!entry) throw new Error("[vitral] n\xE3o achei a entrada do remote (src/remote.* ou src/App.*). Use vitral({ entry }).");
872
- const rolldown = "rolldownVersion" in this.meta;
996
+ rolldown = "rolldownVersion" in (this?.meta ?? {});
997
+ if (next && command === "build" && mode !== "development" && process.env.VITE_USER_NODE_ENV === void 0) process.env.VITE_USER_NODE_ENV = "";
998
+ const whitespace = rolldown && user.build?.minify !== false ? { minify: { codegen: { removeWhitespace: true } } } : {};
873
999
  const dir = options.versionDir ? versionDir(user.root ?? process.cwd(), user.build?.outDir, options.version) : void 0;
874
1000
  return {
875
1001
  // Código de biblioteca não tem process.env; React e Vue precisam disso.
876
- define: { "process.env.NODE_ENV": JSON.stringify(mode === "development" ? "development" : "production") },
1002
+ define: next ? nextDefine({ ...process.env, ...(await import("vite")).loadEnv(mode, user.root ?? process.cwd(), "NEXT_PUBLIC_") }, mode) : { "process.env.NODE_ENV": JSON.stringify(mode === "development" ? "development" : "production") },
877
1003
  server: { cors: true },
878
- ...command === "serve" && { optimizeDeps: devOptimizeDeps(user.plugins, entry, options.adapter) },
879
1004
  preview: { cors: true },
880
1005
  // O remote não tem index.html: sem isso o Vite só descobre as
881
1006
  // dependências no primeiro request e recarrega a página do host.
882
- optimizeDeps: user.optimizeDeps?.entries ? void 0 : { entries: [entry] },
1007
+ optimizeDeps: optimizeDeps(command === "serve", user, entry, options.adapter, next && { rolldown, paths }),
883
1008
  build: mcp ? {
884
1009
  // Um IIFE só, sem chunks: o HTML do MCP App não pode buscar arquivos.
885
1010
  lib: { entry: options.adapter === false ? entry : ENTRY_ID, formats: ["iife"], name: MCP_APP_GLOBAL, fileName: () => "mcp-app.js", cssFileName: "remote" },
@@ -889,8 +1014,14 @@ function vitral(options = {}) {
889
1014
  // Nomes com hash: cache eterno no CDN. Só o vitral.json muda a cada deploy.
890
1015
  lib: { entry: dedupe ? BOOT : options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entry : ENTRY_ID, fileName: () => "remote-[hash].js", cssFileName: "remote" },
891
1016
  // Arquivo único (hosts antigos e caminho com blob:) e build dividido (manifesto v2).
892
- rollupOptions: { external: options.shared ?? [], output: outputs(rolldown, !!options.compileHints) },
1017
+ rollupOptions: {
1018
+ external: options.shared ?? [],
1019
+ output: outputs(rolldown, !!options.compileHints).map((o) => ({ ...o, ...whitespace })),
1020
+ ...options.sideEffectFree?.length && { treeshake: { moduleSideEffects: pureExcept(options.sideEffectFree) } }
1021
+ },
893
1022
  cssCodeSplit: false,
1023
+ // A entrada do dedupe usa top-level await, fora do target padrão do Vite 5 e 6.
1024
+ ...dedupe && !user.build?.target && { target: "es2022" },
894
1025
  ...dir && { outDir: dir }
895
1026
  }
896
1027
  };
@@ -900,14 +1031,21 @@ function vitral(options = {}) {
900
1031
  framework = detectAdapter(c.plugins);
901
1032
  adapter = options.adapter || framework;
902
1033
  serve = c.command === "serve";
1034
+ minify = !serve && c.build.minify !== false;
1035
+ if (!serve && c.mode !== "development" && process.env.NODE_ENV === "development") {
1036
+ throw new Error("[vitral] NODE_ENV=development (de um .env?) num build de produ\xE7\xE3o: o JSX sai com jsxDEV e o remote quebra. Rode com NODE_ENV=production.");
1037
+ }
903
1038
  outDir = resolve4(c.root, c.build.outDir);
904
1039
  try {
905
- pkg = JSON.parse(readFileSync4(join4(root, "package.json"), "utf8"));
1040
+ pkg = JSON.parse(readFileSync5(join5(root, "package.json"), "utf8"));
906
1041
  } catch {
907
1042
  }
908
1043
  },
909
1044
  async buildStart() {
910
- if (dedupe && !serve) shared = await groups(options.dedupe, root, entry, (id, importer) => this.resolve(id, importer, { skipSelf: true }));
1045
+ if (dedupe && !serve) {
1046
+ hooks.reset();
1047
+ shared = await groups(options.dedupe, root, entry, nodeResolve);
1048
+ }
911
1049
  },
912
1050
  // Modo dev: /vitral.json aponta para um módulo com o cliente HMR.
913
1051
  configureServer(server) {
@@ -918,28 +1056,67 @@ function vitral(options = {}) {
918
1056
  // nem chegam ao JS. As checagens nos handlers continuam para Vite 5 e 6.0-6.2.
919
1057
  resolveId: {
920
1058
  order: "pre",
921
- filter: { id: [...dedupe ? [dedupeIds(options.dedupe)] : [], ...options.exposes ? [EXPOSES_IDS] : [], /__vitral_entry__\.js$/, DEV_IDS] },
922
- handler(id, importer) {
1059
+ filter: {
1060
+ id: [
1061
+ ...dedupe ? [dedupeIds(options.dedupe)] : [],
1062
+ ...options.exposes ? [EXPOSES_IDS] : [],
1063
+ ...next ? [NEXT_IDS] : [],
1064
+ // `paths` do tsconfig e dedupe de `pacote/*`: qualquer import que não é relativo.
1065
+ ...paths || files ? [/^[^.\0]/] : [],
1066
+ /__vitral_entry__\.js$/,
1067
+ DEV_IDS
1068
+ ]
1069
+ },
1070
+ async handler(id, importer, opts) {
1071
+ const shim = next && resolveNextId(id);
1072
+ if (shim) return shim;
923
1073
  const own = dedupe && !serve ? hooks.resolveId.handler(id, importer) : null;
924
1074
  if (own) return own;
925
1075
  if (options.exposes && resolveExposesId(id)) return resolveExposesId(id);
926
1076
  if (id.endsWith(ENTRY_ID)) return VIRTUAL_ENTRY;
927
- return resolveDevId(id);
1077
+ const dev = resolveDevId(id);
1078
+ if (dev) return dev;
1079
+ if (!importer || importer.startsWith("\0") || id.startsWith("\0") || /^(\.|\/|[a-zA-Z]:|virtual:)/.test(id)) return null;
1080
+ const byShared = files && !serve && hooks.files();
1081
+ const config = paths ? pathsFor(importer.split("?")[0]) : null;
1082
+ const candidates = config ? pathCandidates(id, config) : void 0;
1083
+ if (!candidates && !byShared) return null;
1084
+ for (const c of candidates ?? [id]) {
1085
+ const r = await this.resolve(c, importer, { ...opts, skipSelf: true });
1086
+ if (!r || r.external) continue;
1087
+ return byShared && await hooks.resolved(this, r.id, importer) || r;
1088
+ }
1089
+ return null;
928
1090
  }
929
1091
  },
930
1092
  load: {
1093
+ // Antes do vite:asset, que faria do .svg uma URL.
1094
+ order: "pre",
931
1095
  // Todos os módulos virtuais do vitral: \0vitral... e \0virtual:vitral...
932
- filter: { id: /^\x00(virtual:)?vitral/ },
933
- handler(id) {
934
- const own = dedupe && !serve ? hooks.load(id) : null;
1096
+ filter: { id: [/^\x00(virtual:)?vitral/, ...next?.svgr !== false && next ? [/\.svg$/] : []] },
1097
+ async handler(id) {
1098
+ if (next && next.svgr !== false && id.endsWith(".svg") && !id.startsWith("\0")) {
1099
+ const svgr = await (svg ??= svgComponents(root));
1100
+ return svgr ? svgr.transform(id) : null;
1101
+ }
1102
+ const own = dedupe && !serve ? await hooks.load(this, id) : null;
935
1103
  if (own != null) return own;
936
1104
  const exposed = options.exposes ? loadExposes(id, root, entry, options.exposes, options.adapter === false ? void 0 : ENTRY_ID) : null;
937
1105
  if (exposed != null) return exposed;
938
- if (id === VIRTUAL_ENTRY) return entryCode(resolve4(root, entry), adapter, scopeName());
1106
+ const shim = next && loadNext(id, next);
1107
+ if (shim) return shim;
1108
+ if (id === VIRTUAL_ENTRY) return entryCode(resolve4(root, entry), adapter, scopeName(), !!next);
939
1109
  if (id === VIRTUAL_DEV_ENTRY) return devEntryCode(framework, options.adapter === false ? resolve4(root, entry) : void 0);
940
1110
  return loadPreamble(id);
941
1111
  }
942
1112
  },
1113
+ // Vite 5-7: depois do minificador do Vite, que no modo lib deixa os espaços.
1114
+ renderChunk: {
1115
+ order: "post",
1116
+ handler(code, chunk, out) {
1117
+ if (minify && !rolldown && out.format === "es") return minifyWhitespace(code, chunk.fileName, !!out.sourcemap);
1118
+ }
1119
+ },
943
1120
  transform: {
944
1121
  filter: { id: DEV_CSS },
945
1122
  handler(code, id) {
@@ -949,20 +1126,20 @@ function vitral(options = {}) {
949
1126
  writeBundle(_, bundle) {
950
1127
  if (options.sbom) bundledFiles(bundle, modules);
951
1128
  if (isSplit(bundle)) return void (split = collect(outDir, bundle));
952
- const files = Object.values(bundle);
953
- const entry2 = files.find((f) => f.type === "chunk" && f.isEntry);
1129
+ const files2 = Object.values(bundle);
1130
+ const entry2 = files2.find((f) => f.type === "chunk" && f.isEntry);
954
1131
  if (!entry2) return;
955
- if (mcp) return mcpApp(files, entry2.fileName);
1132
+ if (mcp) return mcpApp(files2, entry2.fileName);
956
1133
  const emit = (file, text, kind = "") => {
957
1134
  const hash = createHash3("sha256").update(text).digest("base64url").slice(0, 8);
958
1135
  const name = file.replace(/\.css$/, `${kind}-${hash}.css`);
959
- writeFileSync2(join4(outDir, name), text);
1136
+ writeFileSync2(join5(outDir, name), text);
960
1137
  return name;
961
1138
  };
962
1139
  const shadow = { css: [] };
963
- const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => {
964
- const from = join4(outDir, f.fileName);
965
- const text = transformCss(readFileSync4(from, "utf8"), options, scopeName());
1140
+ const css = files2.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => {
1141
+ const from = join5(outDir, f.fileName);
1142
+ const text = transformCss(readFileSync5(from, "utf8"), options, scopeName());
966
1143
  const name = emit(f.fileName, text);
967
1144
  if (name !== f.fileName) rmSync2(from);
968
1145
  const split2 = splitShadowCss(text);
@@ -972,7 +1149,7 @@ function vitral(options = {}) {
972
1149
  if (split2.rebase) shadow.rebase = true;
973
1150
  return name;
974
1151
  });
975
- const code = readFileSync4(join4(outDir, entry2.fileName));
1152
+ const code = readFileSync5(join5(outDir, entry2.fileName));
976
1153
  manifest = {
977
1154
  name: options.name ?? pkg.name ?? "remote",
978
1155
  version: options.version ?? pkg.version,
@@ -989,32 +1166,49 @@ function vitral(options = {}) {
989
1166
  if (!manifest) return;
990
1167
  const done = withSplit(manifest, outDir, split, shared);
991
1168
  if (options.sbom) {
992
- const bom = createSbom({ root, name: done.name, version: done.version, files: modules, entry: readFileSync4(join4(outDir, done.entry)), tool: ownVersion() });
993
- writeFileSync2(join4(outDir, SBOM_FILE), JSON.stringify(bom, null, 2) + "\n");
994
- done.sbom = { file: SBOM_FILE, integrity: sri(join4(outDir, SBOM_FILE)) };
1169
+ const bom = createSbom({ root, name: done.name, version: done.version, files: modules, entry: readFileSync5(join5(outDir, done.entry)), tool: ownVersion() });
1170
+ writeFileSync2(join5(outDir, SBOM_FILE), JSON.stringify(bom, null, 2) + "\n");
1171
+ done.sbom = { file: SBOM_FILE, integrity: sri(join5(outDir, SBOM_FILE)) };
995
1172
  }
996
1173
  manifest = split = void 0;
997
1174
  modules = /* @__PURE__ */ new Set();
998
- writeFileSync2(join4(outDir, "vitral.json"), JSON.stringify(done, null, 2) + "\n");
1175
+ writeFileSync2(join5(outDir, "vitral.json"), JSON.stringify(done, null, 2) + "\n");
999
1176
  const props = options.types === false ? null : await extractProps(root, entryFile());
1000
- if (props) writeFileSync2(join4(outDir, "vitral.d.ts"), typesFile(done.name, props));
1177
+ if (props) writeFileSync2(join5(outDir, "vitral.d.ts"), typesFile(done.name, props));
1001
1178
  }
1002
1179
  };
1003
1180
  }
1181
+ function optimizeDeps(serve, user, entry, adapter, next) {
1182
+ const own = user.optimizeDeps?.entries ? {} : { entries: [entry] };
1183
+ if (!serve) return own;
1184
+ const include = [...devOptimizeDeps(user.plugins, entry, adapter).include, ...next ? ["vitral/next"] : []];
1185
+ return { ...own, include, ...next && next.paths && optimizerPaths(next.rolldown) };
1186
+ }
1187
+ function pureExcept(pkgs) {
1188
+ const dirs = pkgs.map((p) => `/node_modules/${p}/`);
1189
+ return (id) => /\.(css|scss|sass|less|styl)($|\?)/.test(id) || !dirs.some((d) => id.replace(/\\/g, "/").includes(d));
1190
+ }
1191
+ async function nodeResolve(id, importer) {
1192
+ try {
1193
+ return { id: createRequire3(importer).resolve(id) };
1194
+ } catch {
1195
+ return null;
1196
+ }
1197
+ }
1004
1198
  function ownVersion() {
1005
1199
  try {
1006
- return JSON.parse(readFileSync4(new URL("../package.json", import.meta.url), "utf8")).version;
1200
+ return JSON.parse(readFileSync5(new URL("../package.json", import.meta.url), "utf8")).version;
1007
1201
  } catch {
1008
1202
  return void 0;
1009
1203
  }
1010
1204
  }
1011
1205
  function versionDir(root, outDir = "dist", version) {
1012
1206
  try {
1013
- version ??= JSON.parse(readFileSync4(join4(resolve4(root), "package.json"), "utf8")).version;
1207
+ version ??= JSON.parse(readFileSync5(join5(resolve4(root), "package.json"), "utf8")).version;
1014
1208
  } catch {
1015
1209
  }
1016
1210
  if (!version) throw new Error('[vitral] versionDir precisa de uma vers\xE3o: use vitral({ version }) ou "version" no package.json.');
1017
- return join4(outDir, version);
1211
+ return join5(outDir, version);
1018
1212
  }
1019
1213
  function contractOf(version, groups2) {
1020
1214
  const contract = {
@@ -1025,5 +1219,6 @@ function contractOf(version, groups2) {
1025
1219
  }
1026
1220
  export {
1027
1221
  vitral as default,
1222
+ pureExcept,
1028
1223
  vitral
1029
1224
  };