vitral 0.1.0 → 0.3.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 (63) hide show
  1. package/README.md +250 -217
  2. package/dist/angular.d.ts +16 -4
  3. package/dist/angular.js +26 -5
  4. package/dist/auto.d.ts +2 -0
  5. package/dist/auto.js +13 -0
  6. package/dist/capture-JYFERAPL.js +42 -0
  7. package/dist/chunk-3YXI3G34.js +181 -0
  8. package/dist/chunk-AH7KNMBW.js +20 -0
  9. package/dist/chunk-AKNNHQ2H.js +45 -0
  10. package/dist/chunk-DXORSF4X.js +42 -0
  11. package/dist/chunk-GNHCZRQP.js +79 -0
  12. package/dist/chunk-GNPFWISJ.js +80 -0
  13. package/dist/chunk-I3VSKSAZ.js +634 -0
  14. package/dist/chunk-IHTUM6LT.js +152 -0
  15. package/dist/chunk-SDB5AZEI.js +51 -0
  16. package/dist/chunk-TD4S3IHA.js +201 -0
  17. package/dist/chunk-ZAC6QQI6.js +64 -0
  18. package/dist/cli.d.ts +1 -0
  19. package/dist/cli.js +138 -0
  20. package/dist/contract-46EZFQPQ.js +17 -0
  21. package/dist/dedupe-S7BHQMOZ.js +82 -0
  22. package/dist/devtools.d.ts +12 -0
  23. package/dist/devtools.js +86 -0
  24. package/dist/element.d.ts +60 -2
  25. package/dist/element.js +10 -2
  26. package/dist/errors-kjBv6IH_.d.ts +17 -0
  27. package/dist/events-D5gs7rff.d.ts +6 -0
  28. package/dist/expose-JUOUN5N5.js +15 -0
  29. package/dist/host-slot-Cz6EiGsB.d.ts +6 -0
  30. package/dist/iframe.d.ts +28 -0
  31. package/dist/iframe.js +239 -0
  32. package/dist/index.d.ts +144 -147
  33. package/dist/index.js +40 -10
  34. package/dist/navigate-BRG1WJUM.d.ts +9 -0
  35. package/dist/otel.d.ts +44 -0
  36. package/dist/otel.js +27 -0
  37. package/dist/overrides-NZAIUGK5.js +15 -0
  38. package/dist/preact.d.ts +30 -7
  39. package/dist/preact.js +38 -9
  40. package/dist/react.d.ts +46 -7
  41. package/dist/react.js +97 -42
  42. package/dist/routes.d.ts +56 -0
  43. package/dist/routes.js +144 -0
  44. package/dist/sentry.d.ts +25 -0
  45. package/dist/sentry.js +11 -0
  46. package/dist/shadow-6HELCHCJ.js +98 -0
  47. package/dist/slot-DqXTwGbs.d.ts +36 -0
  48. package/dist/solid.d.ts +29 -6
  49. package/dist/solid.js +32 -8
  50. package/dist/sri-JMX6JLQP.js +116 -0
  51. package/dist/state-BDdCwc21.d.ts +4 -0
  52. package/dist/svelte.d.ts +19 -3
  53. package/dist/svelte.js +11 -4
  54. package/dist/testing.d.ts +3 -2
  55. package/dist/testing.js +9 -3
  56. package/dist/types-Czvm-siZ.d.ts +327 -0
  57. package/dist/vite.d.ts +66 -4
  58. package/dist/vite.js +1044 -25
  59. package/dist/vue.d.ts +86 -7
  60. package/dist/vue.js +74 -46
  61. package/package.json +181 -11
  62. package/dist/chunk-IZK6ITIJ.js +0 -96
  63. package/dist/chunk-TTL52BF2.js +0 -547
package/dist/vite.js CHANGED
@@ -1,7 +1,273 @@
1
1
  // src/vite.ts
2
+ import { createHash as createHash2 } from "crypto";
3
+ import { readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
4
+ import { join as join5, resolve as resolve5 } from "path";
5
+
6
+ // src/vite-exposes.ts
7
+ import { resolve } from "path";
8
+ var EXPOSES_ENTRY = "__vitral_exposes__.js";
9
+ var ID = "\0vitral-exposes";
10
+ function exposeKeys(exposes) {
11
+ const out = {};
12
+ for (const [key, file] of Object.entries(exposes)) {
13
+ const clean = key.replace(/^\.?\/?/, "");
14
+ if (!clean) throw new Error(`[vitral] exposes: chave inv\xE1lida "${key}". Use algo como "./MiniCarrinho".`);
15
+ out["./" + clean] = file;
16
+ }
17
+ return out;
18
+ }
19
+ var EXPOSES_IDS = /(^|[\\/])__vitral_exposes__\.js$/;
20
+ function resolveExposesId(id) {
21
+ return id === EXPOSES_ENTRY || id.endsWith("/" + EXPOSES_ENTRY) || id.endsWith("\\" + EXPOSES_ENTRY) ? ID : null;
22
+ }
23
+ function loadExposes(id, root, entry, exposes, main) {
24
+ if (id !== ID) return null;
25
+ const file = (f) => JSON.stringify(resolve(root, f).replace(/\\/g, "/"));
26
+ const parts = Object.entries(exposeKeys(exposes)).map(([key, f]) => ` ${JSON.stringify(key)}: () => import(${file(f)}),`);
27
+ return [`export * from ${file(entry)}`, `export { default } from ${main ? JSON.stringify(main) : file(entry)}`, `export const exposes = {`, ...parts, `}`, ""].join("\n");
28
+ }
29
+
30
+ // src/vite/manifest.ts
2
31
  import { createHash } from "crypto";
3
32
  import { readFileSync, rmSync, writeFileSync } from "fs";
4
- import { join, resolve } from "path";
33
+ import { join, posix } from "path";
34
+ var SPLIT = "split/";
35
+ var sri = (file) => "sha384-" + createHash("sha384").update(readFileSync(file)).digest("base64");
36
+ function outputs(rolldown) {
37
+ return [
38
+ { format: "es", ...rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
39
+ // Os assets saem com o mesmo nome nas duas (o Vite só aceita um padrão).
40
+ { format: "es", entryFileNames: `${SPLIT}remote-[hash].js`, chunkFileNames: `${SPLIT}[name]-[hash].js` }
41
+ ];
42
+ }
43
+ var isSplit = (bundle) => Object.values(bundle).some((f) => f.type === "chunk" && f.isEntry && f.fileName.startsWith(SPLIT));
44
+ var helper = (load = "import", base = "import.meta.url") => `function __vitralImport(u,d){var p=globalThis[Symbol.for("vitral")],s=p&&p.sri,a=d.concat(u).map(function(x){return new URL(x,${base}).href});return Promise.all(s?a.map(function(h){return new Promise(function(ok,no){if(!s[h])return no(new Error("vitral: arquivo sem integrity: "+h));var l=document.createElement("link");l.rel="modulepreload";l.crossOrigin="anonymous";l.integrity=s[h];l.href=h;l.onload=ok;l.onerror=function(){no(new Error("vitral: integrity n\xE3o confere: "+h))};document.head.appendChild(l)})}):[]).then(function(){return ${load}(a[a.length-1])})}`;
45
+ function collect(outDir, bundle) {
46
+ for (const f of Object.values(bundle)) if (f.fileName.endsWith(".css")) rmSync(join(outDir, f.fileName), { force: true });
47
+ const chunks = Object.values(bundle).filter((f) => f.type === "chunk");
48
+ const byName = new Map(chunks.map((c) => [c.fileName, c]));
49
+ const deps = (name, seen = /* @__PURE__ */ new Set()) => {
50
+ for (const d of byName.get(name)?.imports ?? []) if (byName.has(d) && !seen.has(d)) seen.add(d), deps(d, seen);
51
+ return seen;
52
+ };
53
+ const live = /* @__PURE__ */ new Map();
54
+ for (const c of chunks) live.set(c.fileName, rewrite(join(outDir, c.fileName), c, byName, deps));
55
+ const entry = chunks.find((c) => c.isEntry).fileName;
56
+ const used = /* @__PURE__ */ new Set([entry]);
57
+ for (const name of used) for (const d of [...deps(name), ...live.get(name)]) used.add(d);
58
+ if (![...used].some((n) => live.get(n).length)) {
59
+ rmSync(join(outDir, SPLIT), { recursive: true, force: true });
60
+ return;
61
+ }
62
+ for (const c of chunks) if (!used.has(c.fileName)) rmSync(join(outDir, c.fileName), { force: true });
63
+ const own = {};
64
+ for (const c of chunks) if (used.has(c.fileName) && c.facadeModuleId?.startsWith("\0vitral-own:"))
65
+ own[c.facadeModuleId.slice("\0vitral-own:".length)] = { file: c.fileName, chunks: [...deps(c.fileName)] };
66
+ const soon = deps(entry);
67
+ if (Object.keys(own).length) {
68
+ for (const d of live.get(entry)) if (!Object.values(own).some((o) => o.file === d)) soon.add(d), deps(d, soon);
69
+ }
70
+ soon.delete(entry);
71
+ return { entry, chunks: [...soon], files: [...used], own };
72
+ }
73
+ function rewrite(file, c, byName, deps) {
74
+ const targets = c.dynamicImports.filter((d) => byName.has(d));
75
+ if (!targets.length) return [];
76
+ const dir = posix.dirname(c.fileName);
77
+ const rel = (to) => {
78
+ const r = posix.relative(dir, to);
79
+ return r.startsWith(".") ? r : `./${r}`;
80
+ };
81
+ const done = /* @__PURE__ */ new Set();
82
+ const source = readFileSync(file, "utf8");
83
+ let rest = source;
84
+ let code = source.replace(/\bimport\(\s*(["'`])([^"'`]+)\1\s*\)/g, (all, _q, spec) => {
85
+ const target = posix.join(dir, spec);
86
+ if (!targets.includes(target)) return all;
87
+ done.add(target);
88
+ rest = rest.replace(all, "");
89
+ return `__vitralImport(${JSON.stringify(spec)},${JSON.stringify([...deps(target)].map(rel))})`;
90
+ });
91
+ const missing = targets.filter((t) => !done.has(t) && !c.imports.includes(t) && rest.includes(posix.basename(t)));
92
+ if (missing.length) throw new Error(`vitral: n\xE3o foi poss\xEDvel preparar o import() de ${missing.join(", ")} em ${c.fileName}`);
93
+ if (!done.size) return [];
94
+ const map = /\n\/\/# sourceMappingURL=[^\n]*\n?$/.exec(code);
95
+ const at = map ? map.index : code.length;
96
+ code = `${code.slice(0, at)}
97
+ ${helper()}${code.slice(at)}`;
98
+ writeFileSync(file, code);
99
+ return [...done];
100
+ }
101
+ function withSplit(m, outDir, s, groups2 = []) {
102
+ const files = {};
103
+ for (const f of [m.entry, ...m.css ?? [], ...m.shadow?.css ?? [], ...m.shadow?.global ?? [], ...s?.files ?? []]) files[f] = sri(join(outDir, f));
104
+ const dedupe = groups2.filter((g) => s?.own[g.name]).map(({ name, range, version }) => ({ name, range, version, ...s.own[name] }));
105
+ return { ...m, files, ...s && { split: { entry: s.entry, chunks: s.chunks } }, ...dedupe.length && { dedupe } };
106
+ }
107
+
108
+ // src/vite/dedupe.ts
109
+ import { existsSync, readFileSync as readFileSync2 } from "fs";
110
+ import { dirname, join as join2, resolve as resolve2 } from "path";
111
+ import { pathToFileURL } from "url";
112
+ var REACT = ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "react/jsx-dev-runtime", "react/compiler-runtime"];
113
+ var BOOT = "virtual:vitral-boot";
114
+ var DEPS = "\0vitral-deps";
115
+ var OWN = "\0vitral-own:";
116
+ var SHIM = "\0vitral-shim:";
117
+ var pkgOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
118
+ var groupOf = (spec) => REACT.includes(spec) || pkgOf(spec) === "scheduler" ? "react" : pkgOf(spec);
119
+ var ident = /^[A-Za-z_$][\w$]*$/;
120
+ function versionOf(file, pkg) {
121
+ for (let dir = dirname(file); dir !== dirname(dir); dir = dirname(dir)) {
122
+ const json = join2(dir, "package.json");
123
+ if (!existsSync(json)) continue;
124
+ const data = JSON.parse(readFileSync2(json, "utf8"));
125
+ if (data.name === pkg) return data.version;
126
+ }
127
+ throw new Error(`vitral: vers\xE3o de ${pkg} n\xE3o encontrada`);
128
+ }
129
+ async function groups(list, root, entry, resolveId) {
130
+ const importer = resolve2(root, entry);
131
+ const byName = /* @__PURE__ */ new Map();
132
+ for (const spec of list) {
133
+ const g = groupOf(spec);
134
+ byName.set(g, [.../* @__PURE__ */ new Set([...byName.get(g) ?? [], ...g === "react" ? REACT : [spec]])]);
135
+ }
136
+ const out = [];
137
+ for (const [name, specs] of byName) {
138
+ const group = { name, range: "", version: "", keys: [], names: {}, pkgs: name === "react" ? ["react", "react-dom", "scheduler"] : [name] };
139
+ for (const spec of specs) {
140
+ const found = await resolveId(spec, importer);
141
+ if (!found) {
142
+ if (spec === name) throw new Error(`vitral: dedupe: ${spec} n\xE3o est\xE1 instalado`);
143
+ continue;
144
+ }
145
+ const mod = await import(pathToFileURL(found.id.split("?")[0]).href);
146
+ const extra = mod.default && typeof mod.default === "object" ? Object.keys(mod.default) : [];
147
+ group.names[spec] = [.../* @__PURE__ */ new Set([...Object.keys(mod), ...extra])].filter((n) => n !== "default" && ident.test(n));
148
+ group.keys.push(spec);
149
+ if (spec === name) group.version = versionOf(found.id, name);
150
+ }
151
+ group.range = name === "svelte" || name.startsWith("@angular/") ? group.version : `^${group.version}`;
152
+ out.push(group);
153
+ }
154
+ return out;
155
+ }
156
+ var escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\0/g, "\\x00");
157
+ function dedupeIds(list) {
158
+ const specs = new Set(list.flatMap((s) => groupOf(s) === "react" ? REACT : [s]));
159
+ return new RegExp(`${escape(BOOT)}$|^(${[DEPS, ...specs].map(escape).join("|")})$|^(${escape(OWN)}|${escape(SHIM)})`);
160
+ }
161
+ function dedupeHooks(entry, getGroups) {
162
+ const keyOf = (id) => getGroups().find((g) => g.keys.includes(id));
163
+ return {
164
+ resolveId: {
165
+ order: "pre",
166
+ handler(id, importer) {
167
+ if (id.endsWith(BOOT)) return `\0${BOOT}`;
168
+ if (id === DEPS || id.startsWith(OWN) || id.startsWith(SHIM)) return id;
169
+ const g = keyOf(id);
170
+ if (!g || !importer || importer.startsWith(OWN)) return null;
171
+ const norm = importer.replace(/\\/g, "/");
172
+ if (g.pkgs.some((p) => norm.includes(`/node_modules/${p}/`))) return null;
173
+ return SHIM + id;
174
+ }
175
+ },
176
+ load(id) {
177
+ if (id === `\0${BOOT}`) return boot(entry(), getGroups());
178
+ if (id === DEPS) return "export const deps = {}";
179
+ if (id.startsWith(OWN)) {
180
+ const g = getGroups().find((x) => x.name === id.slice(OWN.length));
181
+ return g.keys.map((k, i) => `import * as m${i} from ${JSON.stringify(k)}`).join("\n") + `
182
+ export default {${g.keys.map((k, i) => `${JSON.stringify(k)}: m${i}`).join(", ")}}
183
+ `;
184
+ }
185
+ if (id.startsWith(SHIM)) {
186
+ const spec = id.slice(SHIM.length);
187
+ const names = keyOf(spec).names[spec];
188
+ return `import { deps } from ${JSON.stringify(DEPS)}
189
+ const m = deps[${JSON.stringify(spec)}]
190
+ export default m.default ?? m
191
+ ` + (names.length ? `export const { ${names.join(", ")} } = m
192
+ ` : "");
193
+ }
194
+ return null;
195
+ }
196
+ };
197
+ }
198
+ function boot(entry, groups2) {
199
+ const calls = groups2.map(
200
+ (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))`
201
+ );
202
+ return `const { deps } = await import(${JSON.stringify(DEPS)})
203
+ const p = globalThis[Symbol.for("vitral")]
204
+ const shared = !!(p && p.dedupe) && /\\/split\\/[^/]*$/.test(import.meta.url)
205
+ async function need(name, range, version, keys, load) {
206
+ let m = shared && (await p.dedupe(name, range, { version, load }))
207
+ if (!m || keys.some((k) => !(k in m))) m = await load()
208
+ Object.assign(deps, m)
209
+ }
210
+ await Promise.all([${calls.join(", ")}])
211
+ const remote = await import(${JSON.stringify(entry)})
212
+ export default remote.default
213
+ `;
214
+ }
215
+
216
+ // src/css-build.ts
217
+ import postcss2 from "postcss";
218
+
219
+ // src/css-layers.ts
220
+ function flattenLayers(root) {
221
+ flatten(root);
222
+ }
223
+ function flatten(container) {
224
+ const head = [];
225
+ const layers = /* @__PURE__ */ new Map();
226
+ const rest = [];
227
+ let anonymous = 0;
228
+ const layer = (name) => {
229
+ let nodes = layers.get(name);
230
+ if (!nodes) layers.set(name, nodes = []);
231
+ return nodes;
232
+ };
233
+ for (const node of [...container.nodes]) {
234
+ const at = node.type === "atrule" ? node : null;
235
+ if (at?.name.toLowerCase() === "layer") {
236
+ if (!at.nodes) {
237
+ for (const name of at.params.split(",")) layer(name.trim());
238
+ } else {
239
+ flatten(at);
240
+ layer(at.params.trim() || `\0${anonymous++}`).push(...at.nodes);
241
+ }
242
+ } else if (!layers.size && !rest.length && (node.type === "comment" || /^(?:charset|import)$/i.test(at?.name ?? ""))) {
243
+ head.push(node);
244
+ } else {
245
+ if (at?.nodes) flatten(at);
246
+ rest.push(node);
247
+ }
248
+ }
249
+ if (!layers.size) return;
250
+ container.removeAll();
251
+ container.append(...head, ...[...layers.values()].flat(), ...rest);
252
+ }
253
+ function renameRegisteredProperties(root, scope) {
254
+ const names = [];
255
+ root.walkAtRules(/^property$/i, (rule) => {
256
+ const name = rule.params.trim();
257
+ if (name.startsWith("--tw-")) names.push(name.slice(5).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&"));
258
+ });
259
+ if (!names.length) return;
260
+ const re = new RegExp(`(?<![\\w-])--tw-(${names.join("|")})(?![\\w-])`, "g");
261
+ const to = `--tw-${scope}-$1`;
262
+ root.walk((node) => {
263
+ if (node.type === "decl") {
264
+ node.prop = node.prop.replace(re, to);
265
+ node.value = node.value.replace(re, to);
266
+ } else if (node.type === "atrule") {
267
+ node.params = node.params.replace(re, to);
268
+ }
269
+ });
270
+ }
5
271
 
6
272
  // src/css-scope.ts
7
273
  import postcss from "postcss";
@@ -16,8 +282,12 @@ function scopeSelector(selector, scope) {
16
282
  return `${scope} ${s}`;
17
283
  }
18
284
  function scopeCss(css, scopeName) {
19
- const scope = `[data-vitral-scope="${scopeName}"]`;
20
285
  const root = postcss.parse(css);
286
+ scopeRoot(root, scopeName);
287
+ return root.toString();
288
+ }
289
+ function scopeRoot(root, scopeName) {
290
+ const scope = `[data-vitral-scope="${scopeName}"]`;
21
291
  root.walkRules((rule) => {
22
292
  let p = rule.parent;
23
293
  while (p && p.type !== "root") {
@@ -27,69 +297,818 @@ function scopeCss(css, scopeName) {
27
297
  }
28
298
  rule.selectors = rule.selectors.map((sel) => scopeSelector(sel, scope));
29
299
  });
300
+ }
301
+
302
+ // src/css-theme.ts
303
+ var GLOBAL2 = /^(?::root|:host|html|body)([.:[#][^\s>+~]*)?$/i;
304
+ var CONDITIONAL = /^(?:media|supports|container|scope|starting-style)$/i;
305
+ function hostTheme(root) {
306
+ const theme = /* @__PURE__ */ new Map();
307
+ root.walkRules((rule) => {
308
+ if (!rule.selectors.every((s) => GLOBAL2.test(s.trim()))) return;
309
+ const base = rule.selectors.every((s) => !GLOBAL2.exec(s.trim())[1]) && !insideConditional(rule);
310
+ rule.each((node) => {
311
+ if (node.type !== "decl" || !node.prop.startsWith("--")) return;
312
+ if (base) theme.set(node.prop, node.value.trim());
313
+ node.remove();
314
+ });
315
+ if (!rule.nodes.length) rule.remove();
316
+ });
317
+ if (!theme.size) return;
318
+ root.walkDecls((decl) => {
319
+ if (/var\(/i.test(decl.value)) decl.value = withFallbacks(decl.value, theme, /* @__PURE__ */ new Set());
320
+ });
321
+ }
322
+ function insideConditional(rule) {
323
+ for (let p = rule.parent; p && p.type !== "root"; p = p.parent) {
324
+ if (p.type === "atrule" && CONDITIONAL.test(p.name)) return true;
325
+ }
326
+ return false;
327
+ }
328
+ function withFallbacks(value, theme, seen) {
329
+ return mapVars(value, (name, fallback) => {
330
+ const own = theme.get(name);
331
+ if (own !== void 0 && !seen.has(name)) {
332
+ return `var(${name}, ${withFallbacks(own, theme, new Set(seen).add(name))})`;
333
+ }
334
+ return fallback === void 0 ? `var(${name})` : `var(${name},${withFallbacks(fallback, theme, seen)})`;
335
+ });
336
+ }
337
+ function mapVars(value, fn) {
338
+ let out = "";
339
+ let i = 0;
340
+ for (; ; ) {
341
+ const start = findVar(value, i);
342
+ if (start < 0) return out + value.slice(i);
343
+ const open = start + 4;
344
+ const close = matchParen(value, open);
345
+ if (close < 0) return out + value.slice(i);
346
+ const inner = value.slice(open, close);
347
+ const comma = topLevelComma(inner);
348
+ const name = (comma < 0 ? inner : inner.slice(0, comma)).trim();
349
+ out += value.slice(i, start) + fn(name, comma < 0 ? void 0 : inner.slice(comma + 1));
350
+ i = close + 1;
351
+ }
352
+ }
353
+ function findVar(value, from) {
354
+ const re = /var\(/gi;
355
+ re.lastIndex = from;
356
+ for (let m = re.exec(value); m; m = re.exec(value)) {
357
+ if (!/[\w-]/.test(value[m.index - 1] ?? "")) return m.index;
358
+ }
359
+ return -1;
360
+ }
361
+ function matchParen(s, open) {
362
+ let depth = 1;
363
+ let quote = "";
364
+ for (let i = open; i < s.length; i++) {
365
+ const c = s[i];
366
+ if (c === "\\") i++;
367
+ else if (quote) quote = c === quote ? "" : quote;
368
+ else if (c === '"' || c === "'") quote = c;
369
+ else if (c === "(") depth++;
370
+ else if (c === ")" && !--depth) return i;
371
+ }
372
+ return -1;
373
+ }
374
+ function topLevelComma(s) {
375
+ let depth = 0;
376
+ let quote = "";
377
+ for (let i = 0; i < s.length; i++) {
378
+ const c = s[i];
379
+ if (c === "\\") i++;
380
+ else if (quote) quote = c === quote ? "" : quote;
381
+ else if (c === '"' || c === "'") quote = c;
382
+ else if (c === "(") depth++;
383
+ else if (c === ")") depth--;
384
+ else if (c === "," && !depth) return i;
385
+ }
386
+ return -1;
387
+ }
388
+
389
+ // src/css-build.ts
390
+ function transformCss(css, options, scope) {
391
+ const root = postcss2.parse(css);
392
+ if (options.theme === "host") hostTheme(root);
393
+ if (options.layers === "flatten") flattenLayers(root);
394
+ if (options.renameRegisteredProperties) renameRegisteredProperties(root, scope);
395
+ if (options.scopeCss !== false) scopeRoot(root, scope);
30
396
  return root.toString();
31
397
  }
398
+ var RELATIVE_URL = /url\(\s*(['"]?)(?![a-z]+:|\/\/|#)([^'")]+)\1\s*\)/i;
399
+ var IMPORT_URL = /^\s*(?:url\(\s*(['"]?)([^'")]+)\1\s*\)|(['"])(.*?)\3)/i;
400
+ function splitShadowCss(text) {
401
+ const root = postcss2.parse(text);
402
+ const global = [];
403
+ const imports = [];
404
+ root.walkAtRules((rule) => {
405
+ const name = rule.name.toLowerCase();
406
+ if (name === "import" && rule.parent === root) {
407
+ const m = IMPORT_URL.exec(rule.params);
408
+ if (m) imports.push(m[2] ?? m[4]);
409
+ rule.remove();
410
+ } else if (name === "property" || name === "font-face") {
411
+ global.push(rule.toString());
412
+ rule.remove();
413
+ }
414
+ });
415
+ const css = global.length || imports.length ? root.toString() : text;
416
+ return { css, global: global.join("\n"), imports, rebase: RELATIVE_URL.test(css) };
417
+ }
418
+
419
+ // src/vite/adapter.ts
420
+ import { existsSync as existsSync2 } from "fs";
421
+ import { resolve as resolve3 } from "path";
422
+ var PLUGINS = [
423
+ [/^(preact:|prefresh$)/, "preact"],
424
+ [/^vite:react/, "react"],
425
+ [/^vite:vue$/, "vue"],
426
+ [/^vite-plugin-svelte/, "svelte"],
427
+ [/^solid$/, "solid"],
428
+ [/^@analogjs\/vite-plugin-angular$/, "angular"]
429
+ ];
430
+ function detectAdapter(plugins) {
431
+ for (const [re, adapter] of PLUGINS) if (plugins.some((p) => re.test(p.name))) return adapter;
432
+ return "element";
433
+ }
434
+ var WRAP = {
435
+ react: ["vitral/react", "reactRemote"],
436
+ vue: ["vitral/vue", "vueRemote"],
437
+ svelte: ["vitral/svelte", "svelteRemote"],
438
+ solid: ["vitral/solid", "solidRemote"],
439
+ preact: ["vitral/preact", "preactRemote"],
440
+ angular: ["vitral/angular", "angularRemote"]
441
+ };
442
+ var ENTRY_ID = "__vitral_entry__.js";
443
+ var VIRTUAL_ENTRY = "\0vitral:entry";
444
+ function entryCode(file, adapter, scope) {
445
+ const head = `import * as m from ${JSON.stringify(file)}
446
+ const c = m.default ?? m
447
+ `;
448
+ if (adapter !== "element") {
449
+ const [from, fn] = WRAP[adapter];
450
+ return `${head}import { ${fn} as wrap } from '${from}'
451
+ export default typeof c?.mount === 'function' ? c : wrap(c)
452
+ `;
453
+ }
454
+ return `${head}import { elementRemote } from 'vitral/element'
455
+ import { component } from 'vitral'
456
+ function wrap(c) {
457
+ if (typeof c === 'function' && typeof HTMLElement !== 'undefined' && c.prototype instanceof HTMLElement) {
458
+ const base = ${JSON.stringify(`${scope}-remote`.toLowerCase().replace(/^[^a-z]+/, "x-"))}
459
+ let tag = customElements.getName?.(c) || base
460
+ // Uma tag n\xE3o aceita outra classe: no HMR, a classe nova ganha tag nova.
461
+ for (let n = 2; customElements.get(tag) && customElements.get(tag) !== c; n++) tag = base + '-' + n
462
+ return elementRemote(tag, () => customElements.get(tag) || customElements.define(tag, c))
463
+ }
464
+ if (typeof c === 'function') return component(c)
465
+ throw new Error('[vitral] o export default n\xE3o \xE9 um remote: exporte um componente, uma fun\xE7\xE3o ou um objeto com mount()')
466
+ }
467
+ export default typeof c?.mount === 'function' ? c : wrap(c)
468
+ `;
469
+ }
470
+ var CANDIDATES = ["src/remote", "src/App", "src/app"];
471
+ var EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".vue", ".svelte"];
472
+ function findEntry(root) {
473
+ for (const base of CANDIDATES) {
474
+ for (const ext of EXTENSIONS) if (existsSync2(resolve3(root, base + ext))) return base + ext;
475
+ }
476
+ }
477
+
478
+ // src/vite/types.ts
479
+ import { createRequire as createRequire2 } from "module";
480
+ import { join as join4 } from "path";
481
+
482
+ // src/vite/oxc.ts
483
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
484
+ import { createRequire } from "module";
485
+ import { dirname as dirname2, join as join3, resolve as resolve4 } from "path";
486
+ import { pathToFileURL as pathToFileURL2 } from "url";
487
+ async function loadOxc(root) {
488
+ const req = createRequire(join3(root, "package.json"));
489
+ const ids = [() => req.resolve("oxc-transform"), () => createRequire(req.resolve("vite/package.json")).resolve("rolldown/experimental")];
490
+ for (const id of ids) {
491
+ try {
492
+ const mod = await import(pathToFileURL2(id()).href);
493
+ if (typeof mod.isolatedDeclarationSync === "function") return mod;
494
+ } catch {
495
+ }
496
+ }
497
+ return null;
498
+ }
499
+ var GLOBAL3 = /^(Date|RegExp|Error|Map|Set|WeakMap|WeakSet|Promise|PromiseLike|Record|Partial|Required|Readonly|Pick|Omit|URL|URLSearchParams|Blob|File|FormData|Headers|AbortSignal|EventTarget|Node|Element|Document|DocumentFragment|ShadowRoot|Window|(HTML|SVG)\w*Element|\w*Event)$/;
500
+ var IDENT = /^[A-Za-z_$][\w$]*$/;
501
+ var Unsupported = class extends Error {
502
+ };
503
+ var unsupported = () => {
504
+ throw new Unsupported();
505
+ };
506
+ function propsFromOxc(ts, oxc, file) {
507
+ try {
508
+ const reader = new Reader(ts, oxc);
509
+ const scope = reader.scope(file);
510
+ const props = reader.defaultProps(scope);
511
+ return props ? reader.print(props.node, props.scope, 0, { top: true }) : "Record<string, unknown>";
512
+ } catch {
513
+ return null;
514
+ }
515
+ }
516
+ var Reader = class {
517
+ constructor(ts, oxc) {
518
+ this.ts = ts;
519
+ this.oxc = oxc;
520
+ this.scopes = /* @__PURE__ */ new Map();
521
+ this.seen = /* @__PURE__ */ new Set();
522
+ }
523
+ /** Declarações de um arquivo: `.d.ts` como está, o resto pelo Oxc. */
524
+ scope(file) {
525
+ const cached = this.scopes.get(file);
526
+ if (cached) return cached;
527
+ const { ts } = this;
528
+ let code = readFileSync3(file, "utf8");
529
+ if (!/\.d\.[cm]?ts$/.test(file)) {
530
+ const out = this.oxc.isolatedDeclarationSync(file, code, {});
531
+ if (out.errors.length) unsupported();
532
+ code = out.code;
533
+ }
534
+ const source = ts.createSourceFile(file + ".d.ts", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
535
+ const scope = { file, types: /* @__PURE__ */ new Map(), values: /* @__PURE__ */ new Map(), imports: /* @__PURE__ */ new Map() };
536
+ const isDefault = (n) => ts.canHaveModifiers(n) && !!ts.getModifiers(n)?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);
537
+ let defaultName;
538
+ for (const st of source.statements) {
539
+ if (ts.isInterfaceDeclaration(st) || ts.isTypeAliasDeclaration(st)) {
540
+ if (scope.types.has(st.name.text)) unsupported();
541
+ scope.types.set(st.name.text, st);
542
+ } else if (ts.isImportDeclaration(st) && ts.isStringLiteral(st.moduleSpecifier)) {
543
+ const from = st.moduleSpecifier.text;
544
+ const clause = st.importClause;
545
+ if (clause?.name) scope.imports.set(clause.name.text, { from, name: "default" });
546
+ const bindings = clause?.namedBindings;
547
+ if (bindings && ts.isNamespaceImport(bindings)) scope.imports.set(bindings.name.text, { from, name: "*" });
548
+ if (bindings && ts.isNamedImports(bindings)) for (const el of bindings.elements) scope.imports.set(el.name.text, { from, name: (el.propertyName ?? el.name).text });
549
+ } else if (ts.isFunctionDeclaration(st) || ts.isClassDeclaration(st)) {
550
+ if (isDefault(st)) scope.default ??= st;
551
+ else if (st.name && !scope.values.has(st.name.text)) scope.values.set(st.name.text, st);
552
+ } else if (ts.isVariableStatement(st)) {
553
+ for (const d of st.declarationList.declarations) if (ts.isIdentifier(d.name)) scope.values.set(d.name.text, d);
554
+ } else if (ts.isExportAssignment(st) && !st.isExportEquals) {
555
+ defaultName = ts.isIdentifier(st.expression) ? st.expression.text : unsupported();
556
+ } else if (ts.isExportDeclaration(st) && !st.moduleSpecifier && st.exportClause && ts.isNamedExports(st.exportClause)) {
557
+ const el = st.exportClause.elements.find((e) => e.name.text === "default");
558
+ if (el) defaultName = (el.propertyName ?? el.name).text;
559
+ }
560
+ }
561
+ if (defaultName) scope.default = scope.values.get(defaultName);
562
+ this.scopes.set(file, scope);
563
+ return scope;
564
+ }
565
+ /** `mount(el, props)`, componente-função `(props)` ou classe com `props`. `undefined`: sem props. */
566
+ defaultProps(scope) {
567
+ const { ts } = this;
568
+ const node = scope.default ?? unsupported();
569
+ const param = (params, i) => {
570
+ const p = params[i];
571
+ return p && { node: p.type ?? unsupported(), scope };
572
+ };
573
+ if (ts.isFunctionDeclaration(node)) return param(node.parameters, 0);
574
+ if (ts.isClassDeclaration(node)) {
575
+ if (node.heritageClauses?.length) unsupported();
576
+ const props = node.members.find((m) => ts.isPropertyDeclaration(m) && m.name.getText() === "props");
577
+ return props && { node: props.type ?? unsupported(), scope };
578
+ }
579
+ if (ts.isVariableDeclaration(node)) return this.propsOfType(node.type ?? unsupported(), scope);
580
+ return unsupported();
581
+ }
582
+ propsOfType(node, scope) {
583
+ const { ts } = this;
584
+ const param = (params, i, at2) => {
585
+ const p = params[i];
586
+ return p && { node: p.type ?? unsupported(), scope: at2 };
587
+ };
588
+ if (ts.isParenthesizedTypeNode(node)) return this.propsOfType(node.type, scope);
589
+ if (ts.isFunctionTypeNode(node)) return param(node.parameters, 0, scope);
590
+ let members;
591
+ let at = scope;
592
+ if (ts.isTypeLiteralNode(node)) members = node.members;
593
+ else if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && !node.typeArguments) {
594
+ const found = this.lookup(node.typeName.text, scope);
595
+ if (!found || found === "package" || found.decl.typeParameters) return unsupported();
596
+ if (ts.isTypeAliasDeclaration(found.decl)) return this.propsOfType(found.decl.type, found.scope);
597
+ if (found.decl.heritageClauses?.length) unsupported();
598
+ members = found.decl.members;
599
+ at = found.scope;
600
+ } else return unsupported();
601
+ const mount = members.find((m) => m.name?.getText() === "mount");
602
+ if (mount) {
603
+ if (ts.isMethodSignature(mount)) return param(mount.parameters, 1, at);
604
+ if (ts.isPropertySignature(mount) && mount.type) return this.mountProps(mount.type, at);
605
+ return unsupported();
606
+ }
607
+ const call = members.find(ts.isCallSignatureDeclaration);
608
+ if (call) return param(call.parameters, 0, at);
609
+ if (members.some(ts.isConstructSignatureDeclaration)) unsupported();
610
+ return void 0;
611
+ }
612
+ mountProps(node, scope) {
613
+ const { ts } = this;
614
+ if (ts.isParenthesizedTypeNode(node)) return this.mountProps(node.type, scope);
615
+ if (!ts.isFunctionTypeNode(node)) return unsupported();
616
+ const p = node.parameters[1];
617
+ return p && { node: p.type ?? unsupported(), scope };
618
+ }
619
+ /** Acha um tipo pelo nome: no arquivo, num import relativo ou num pacote. */
620
+ lookup(name, scope) {
621
+ const decl = scope.types.get(name);
622
+ if (decl) return { decl, scope };
623
+ const imp = scope.imports.get(name);
624
+ if (!imp) return void 0;
625
+ if (!imp.from.startsWith(".")) return "package";
626
+ if (imp.name === "default" || imp.name === "*") return unsupported();
627
+ const found = this.lookup(imp.name, this.scope(resolveFile(scope.file, imp.from)));
628
+ return found ?? unsupported();
629
+ }
630
+ print(node, scope, depth, opts = {}) {
631
+ const { ts } = this;
632
+ const K = ts.SyntaxKind;
633
+ switch (node.kind) {
634
+ case K.AnyKeyword:
635
+ case K.UnknownKeyword:
636
+ return "unknown";
637
+ case K.StringKeyword:
638
+ case K.NumberKeyword:
639
+ case K.BooleanKeyword:
640
+ case K.BigIntKeyword:
641
+ case K.SymbolKeyword:
642
+ case K.UndefinedKeyword:
643
+ case K.VoidKeyword:
644
+ case K.NeverKeyword:
645
+ return node.getText();
646
+ }
647
+ if (ts.isLiteralTypeNode(node)) {
648
+ const lit = node.literal;
649
+ if (ts.isStringLiteral(lit)) return JSON.stringify(lit.text);
650
+ if (lit.kind === K.NullKeyword || lit.kind === K.TrueKeyword || lit.kind === K.FalseKeyword || ts.isNumericLiteral(lit) || ts.isPrefixUnaryExpression(lit)) return lit.getText();
651
+ return unsupported();
652
+ }
653
+ if (ts.isParenthesizedTypeNode(node)) return this.print(node.type, scope, depth, opts);
654
+ if (ts.isUnionTypeNode(node)) {
655
+ const types = opts.nonNull ? node.types.filter((t) => t.kind !== K.UndefinedKeyword && !(ts.isLiteralTypeNode(t) && t.literal.kind === K.NullKeyword)) : node.types;
656
+ const parts = [...new Set(types.map((t) => this.print(t, scope, depth)))];
657
+ if (parts.includes("true") && parts.includes("false")) parts.splice(parts.indexOf("true"), 1, "boolean"), parts.splice(parts.indexOf("false"), 1);
658
+ return parts.join(" | ");
659
+ }
660
+ if (ts.isIntersectionTypeNode(node)) {
661
+ return node.types.map((t) => {
662
+ const s = this.print(t, scope, depth);
663
+ return ts.isUnionTypeNode(t) ? `(${s})` : s;
664
+ }).join(" & ");
665
+ }
666
+ if (depth > 6) return "unknown";
667
+ if (ts.isArrayTypeNode(node)) return `Array<${this.print(node.elementType, scope, depth + 1)}>`;
668
+ if (ts.isTypeOperatorNode(node) && node.operator === K.ReadonlyKeyword && (ts.isArrayTypeNode(node.type) || ts.isTupleTypeNode(node.type))) return this.print(node.type, scope, depth);
669
+ if (ts.isTupleTypeNode(node)) {
670
+ if (node.elements.some((e) => ts.isNamedTupleMember(e) || ts.isOptionalTypeNode(e) || ts.isRestTypeNode(e))) unsupported();
671
+ return `[${node.elements.map((e) => this.print(e, scope, depth + 1)).join(", ")}]`;
672
+ }
673
+ if (ts.isTypeLiteralNode(node)) return this.object(node.members, scope, depth, !!opts.top);
674
+ if (ts.isFunctionTypeNode(node)) return this.signature(node, scope, depth);
675
+ if (ts.isTypeReferenceNode(node)) return this.reference(node, scope, depth, opts);
676
+ return unsupported();
677
+ }
678
+ reference(node, scope, depth, opts) {
679
+ const { ts } = this;
680
+ if (!ts.isIdentifier(node.typeName)) return unsupported();
681
+ const name = node.typeName.text;
682
+ const args = node.typeArguments ?? [];
683
+ const found = this.lookup(name, scope);
684
+ if (found === "package") return "unknown";
685
+ if (found) {
686
+ if (args.length || found.decl.typeParameters) unsupported();
687
+ if (this.seen.has(found.decl)) return "unknown";
688
+ this.seen.add(found.decl);
689
+ try {
690
+ const decl = found.decl;
691
+ if (ts.isTypeAliasDeclaration(decl)) return this.print(decl.type, found.scope, depth, opts);
692
+ if (decl.heritageClauses?.length) unsupported();
693
+ return this.object(decl.members, found.scope, depth, !!opts.top);
694
+ } finally {
695
+ this.seen.delete(found.decl);
696
+ }
697
+ }
698
+ if ((name === "Array" || name === "ReadonlyArray") && args.length === 1) return `Array<${this.print(args[0], scope, depth + 1)}>`;
699
+ if (!GLOBAL3.test(name)) return unsupported();
700
+ return args.length ? `${name}<${args.map((t) => this.print(t, scope, depth + 1)).join(", ")}>` : name;
701
+ }
702
+ object(members, scope, depth, top) {
703
+ const { ts } = this;
704
+ const fields = [];
705
+ const calls = [];
706
+ let index;
707
+ for (const m of members) {
708
+ if (ts.isPropertySignature(m) || ts.isMethodSignature(m)) {
709
+ const name = ts.isIdentifier(m.name) || ts.isStringLiteral(m.name) || ts.isNumericLiteral(m.name) ? m.name.text : unsupported();
710
+ if (top && name === "vitral") continue;
711
+ const optional = m.questionToken ? "?" : "";
712
+ const key = IDENT.test(name) ? name : JSON.stringify(name);
713
+ const type = ts.isMethodSignature(m) ? this.signature(m, scope, depth + 1) : m.type ? this.print(m.type, scope, depth + 1, { nonNull: !!optional }) : "unknown";
714
+ fields.push(`${key}${optional}: ${type}`);
715
+ } else if (ts.isIndexSignatureDeclaration(m)) {
716
+ const key = m.parameters[0]?.type;
717
+ if (!key || key.kind !== ts.SyntaxKind.StringKeyword) unsupported();
718
+ index = `[key: string]: ${this.print(m.type, scope, depth + 1)}`;
719
+ } else if (ts.isCallSignatureDeclaration(m)) {
720
+ calls.push(this.signature(m, scope, depth));
721
+ } else unsupported();
722
+ }
723
+ if (calls.length && !fields.length) return calls[0];
724
+ if (index) fields.push(index);
725
+ for (const c of calls) fields.push(c.replace(" =>", ":"));
726
+ return fields.length ? `{ ${fields.join("; ")} }` : "{}";
727
+ }
728
+ signature(sig, scope, depth) {
729
+ const { ts } = this;
730
+ if (sig.typeParameters?.length || !sig.type) unsupported();
731
+ const params = sig.parameters.map((p, i) => {
732
+ if (p.dotDotDotToken || ts.isIdentifier(p.name) && p.name.text === "this") unsupported();
733
+ const name = ts.isIdentifier(p.name) && IDENT.test(p.name.text) ? p.name.text : `a${i}`;
734
+ const type = p.type ? this.print(p.type, scope, depth + 1) : "unknown";
735
+ return `${name}: ${p.questionToken || p.initializer ? `${type} | undefined` : type}`;
736
+ });
737
+ return `(${params.join(", ")}) => ${this.print(sig.type, scope, depth + 1)}`;
738
+ }
739
+ };
740
+ function resolveFile(from, spec) {
741
+ const base = resolve4(dirname2(from), spec);
742
+ const stem = base.replace(/\.[cm]?jsx?$/, "");
743
+ const candidates = [base, ...[".ts", ".tsx", ".mts", ".cts", ".d.ts"].map((ext) => stem + ext), ...["index.ts", "index.tsx", "index.d.ts"].map((f) => join3(base, f))];
744
+ const file = candidates.find((f) => /\.[cm]?tsx?$/.test(f) && existsSync3(f));
745
+ return file ?? unsupported();
746
+ }
747
+
748
+ // src/vite/types.ts
749
+ function typesFile(name, props) {
750
+ return `// Props do remote ${JSON.stringify(name)}, geradas pelo vitral. N\xE3o edite.
751
+ export type Props = ${props}
752
+ `;
753
+ }
754
+ async function loadTs(root) {
755
+ const api = (ts) => typeof ts?.createProgram === "function" ? ts : null;
756
+ try {
757
+ const ts = api(createRequire2(join4(root, "package.json"))("typescript"));
758
+ if (ts) return ts;
759
+ } catch {
760
+ }
761
+ try {
762
+ return api((await import("typescript")).default);
763
+ } catch {
764
+ return null;
765
+ }
766
+ }
767
+ async function extractProps(root, file) {
768
+ if (!/\.[cm]?[jt]sx?$/.test(file)) return null;
769
+ const ts = await loadTs(root);
770
+ if (!ts) return null;
771
+ const oxc = /\.[cm]?tsx?$/.test(file) ? await loadOxc(root) : null;
772
+ const fast = oxc && propsFromOxc(ts, oxc, file);
773
+ if (fast) return fast;
774
+ const configPath = ts.findConfigFile(root, ts.sys.fileExists);
775
+ const base = configPath ? ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, ts.sys.readFile).config, ts.sys, root).options : {};
776
+ const options = {
777
+ target: ts.ScriptTarget.ES2022,
778
+ module: ts.ModuleKind.ESNext,
779
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
780
+ jsx: ts.JsxEmit.Preserve,
781
+ strict: true,
782
+ ...base,
783
+ allowJs: true,
784
+ skipLibCheck: true,
785
+ noEmit: true
786
+ };
787
+ const program = ts.createProgram([file], options);
788
+ const checker = program.getTypeChecker();
789
+ const source = program.getSourceFile(file);
790
+ const moduleSymbol = source && checker.getSymbolAtLocation(source);
791
+ let symbol = moduleSymbol && checker.getExportsOfModule(moduleSymbol).find((s) => s.escapedName === "default");
792
+ if (!source || !symbol) return null;
793
+ if (symbol.flags & ts.SymbolFlags.Alias) symbol = checker.getAliasedSymbol(symbol);
794
+ const type = checker.getTypeOfSymbolAtLocation(symbol, source);
795
+ const props = propsOf(checker, type, source);
796
+ return props ? new Printer(ts, checker, program).print(props, 0, true) : "Record<string, unknown>";
797
+ }
798
+ function propsOf(checker, type, at) {
799
+ const param = (t, i) => {
800
+ const p = t.getCallSignatures()[0]?.parameters[i];
801
+ return p && checker.getTypeOfSymbolAtLocation(p, at);
802
+ };
803
+ const mount = type.getProperty("mount");
804
+ if (mount) return param(checker.getTypeOfSymbolAtLocation(mount, at), 1);
805
+ if (type.getCallSignatures().length) return param(type, 0);
806
+ const ctor = type.getConstructSignatures()[0];
807
+ const props = ctor?.getReturnType().getProperty("props");
808
+ return props && checker.getTypeOfSymbolAtLocation(props, at);
809
+ }
810
+ var Printer = class {
811
+ constructor(ts, checker, program) {
812
+ this.ts = ts;
813
+ this.checker = checker;
814
+ this.program = program;
815
+ this.seen = /* @__PURE__ */ new Set();
816
+ }
817
+ /** Declarado na lib padrão (Date, Map…): vale em qualquer projeto pelo nome. */
818
+ fromLib(type) {
819
+ const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
820
+ return !!decl && this.program.isSourceFileDefaultLibrary(decl.getSourceFile());
821
+ }
822
+ fromPackage(type) {
823
+ const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
824
+ return !!decl && /[/\\]node_modules[/\\]/.test(decl.getSourceFile().fileName);
825
+ }
826
+ print(type, depth, top = false) {
827
+ const { ts, checker } = this;
828
+ const f = type.flags;
829
+ if (f & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return "unknown";
830
+ if (f & (ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BooleanLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Never | ts.TypeFlags.ESSymbolLike)) {
831
+ return checker.typeToString(type);
832
+ }
833
+ if (type.isUnion()) {
834
+ const parts = [...new Set(type.types.map((t) => this.print(t, depth)))];
835
+ if (parts.includes("true") && parts.includes("false")) parts.splice(parts.indexOf("true"), 1, "boolean"), parts.splice(parts.indexOf("false"), 1);
836
+ return parts.join(" | ");
837
+ }
838
+ if (type.isIntersection()) return type.types.map((t) => this.wrap(t, depth)).join(" & ");
839
+ if (depth > 6 || this.seen.has(type)) return "unknown";
840
+ if (checker.isArrayType(type)) return `Array<${this.print(checker.getTypeArguments(type)[0], depth + 1)}>`;
841
+ if (checker.isTupleType(type)) return `[${checker.getTypeArguments(type).map((t) => this.print(t, depth + 1)).join(", ")}]`;
842
+ if (this.fromLib(type)) {
843
+ const args = type.aliasTypeArguments ?? (type.objectFlags & ts.ObjectFlags.Reference ? checker.getTypeArguments(type) : []);
844
+ const name = (type.aliasSymbol ?? type.getSymbol()).name;
845
+ return args.length ? `${name}<${args.map((t) => this.print(t, depth + 1)).join(", ")}>` : checker.typeToString(type);
846
+ }
847
+ if (this.fromPackage(type)) return "unknown";
848
+ this.seen.add(type);
849
+ try {
850
+ const calls = type.getCallSignatures();
851
+ const props = checker.getPropertiesOfType(type).filter((p) => !(top && p.name === "vitral"));
852
+ if (calls.length && !props.length) return this.signature(calls[0], depth);
853
+ const fields = props.map((p) => {
854
+ const optional = p.flags & ts.SymbolFlags.Optional ? "?" : "";
855
+ const key = /^[A-Za-z_$][\w$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
856
+ const t = checker.getTypeOfSymbol(p);
857
+ return `${key}${optional}: ${this.print(optional ? checker.getNonNullableType(t) : t, depth + 1)}`;
858
+ });
859
+ const index = type.getStringIndexType();
860
+ if (index) fields.push(`[key: string]: ${this.print(index, depth + 1)}`);
861
+ for (const c of calls) fields.push(this.signature(c, depth).replace(" =>", ":"));
862
+ return fields.length ? `{ ${fields.join("; ")} }` : "{}";
863
+ } finally {
864
+ this.seen.delete(type);
865
+ }
866
+ }
867
+ wrap(type, depth) {
868
+ const s = this.print(type, depth);
869
+ return type.isUnion() ? `(${s})` : s;
870
+ }
871
+ signature(sig, depth) {
872
+ const params = sig.parameters.map((p, i) => `${/^[A-Za-z_$][\w$]*$/.test(p.name) ? p.name : `a${i}`}: ${this.print(this.checker.getTypeOfSymbol(p), depth + 1)}`);
873
+ return `(${params.join(", ")}) => ${this.print(sig.getReturnType(), depth + 1)}`;
874
+ }
875
+ };
876
+
877
+ // src/vite/dev.ts
878
+ var DEV_ENTRY = "@vitral/entry.js";
879
+ var VIRTUAL_DEV_ENTRY = "\0vitral:dev-entry";
880
+ var PREAMBLE_ID = "virtual:vitral-react-preamble";
881
+ var REACT_PREAMBLE = `import { injectIntoGlobalHook } from '/@react-refresh'
882
+ injectIntoGlobalHook(window)
883
+ window.$RefreshReg$ ??= () => {}
884
+ window.$RefreshSig$ ??= () => (type) => type
885
+ window.__vite_plugin_react_preamble_installed__ = true
886
+ `;
887
+ function devEntryCode(framework, raw) {
888
+ const preamble = framework === "react" ? `import '${PREAMBLE_ID}'
889
+ ` : "";
890
+ const from = raw ? JSON.stringify(raw) : `'${ENTRY_ID}'`;
891
+ return `import '/@vite/client'
892
+ ${preamble}import * as first from ${from}
893
+ let mod = first.default ?? first
894
+ const live = new Set()
895
+ export default {
896
+ async mount(el, props, ctx) {
897
+ const i = { props, handle: await mod.mount(el, props, ctx) }
898
+ i.remount = async () => {
899
+ i.handle.unmount()
900
+ el.replaceChildren()
901
+ i.handle = await mod.mount(el, i.props, ctx)
902
+ }
903
+ live.add(i)
904
+ return {
905
+ update(next) {
906
+ i.props = next
907
+ i.handle.update?.(next)
908
+ },
909
+ unmount() {
910
+ live.delete(i)
911
+ i.handle.unmount()
912
+ },
913
+ }
914
+ },
915
+ }
916
+ if (import.meta.hot) {
917
+ import.meta.hot.accept(${from}, (next) => {
918
+ if (!next) return import.meta.hot.invalidate()
919
+ mod = next.default ?? next
920
+ for (const i of live) i.remount().catch((e) => console.error('[vitral] falha ao remontar depois da edi\xE7\xE3o', e))
921
+ })
922
+ }
923
+ `;
924
+ }
925
+ var DEV_IDS = /^virtual:vitral-react-preamble$|\/@vitral\/entry\.js$/;
926
+ function resolveDevId(id) {
927
+ if (id === PREAMBLE_ID) return "\0" + PREAMBLE_ID;
928
+ if (id.endsWith("/" + DEV_ENTRY)) return VIRTUAL_DEV_ENTRY;
929
+ }
930
+ function loadPreamble(id) {
931
+ if (id === "\0" + PREAMBLE_ID) return REACT_PREAMBLE;
932
+ }
933
+ function devManifest(name, scope) {
934
+ return { name, entry: DEV_ENTRY, css: [], ...scope ? { scope } : {} };
935
+ }
936
+ var DEV_CSS = { include: /\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(\?|$)/, exclude: /[?&](raw|url|inline)\b/ };
937
+ function scopeDevCss(code, id, scope) {
938
+ if (!DEV_CSS.include.test(id) || DEV_CSS.exclude.test(id)) return;
939
+ return scopeCss(code, scope);
940
+ }
941
+ function serveDevManifest(server, manifest) {
942
+ const path = `${server.config.base.replace(/\/?$/, "/")}vitral.json`;
943
+ server.httpServer?.once("listening", () => {
944
+ const address = server.httpServer.address();
945
+ if (!server.config.server.origin && address && typeof address === "object") {
946
+ const protocol = server.config.server.https ? "https" : "http";
947
+ server.config.server.origin = `${protocol}://localhost:${address.port}`;
948
+ }
949
+ });
950
+ server.middlewares.use((req, res, next) => {
951
+ if (req.url?.split("?")[0] !== path) return next();
952
+ res.writeHead(200, {
953
+ "content-type": "application/json",
954
+ "cache-control": "no-store",
955
+ "access-control-allow-origin": "*"
956
+ });
957
+ res.end(JSON.stringify(manifest(), null, 2));
958
+ });
959
+ }
960
+ function devOptimizeDeps(plugins, entry, adapter) {
961
+ const named = [plugins].flat(Infinity).filter((p) => typeof p?.name === "string");
962
+ const fw = adapter === false ? null : adapter || detectAdapter(named);
963
+ const include = fw === null ? [] : fw === "element" ? ["vitral", "vitral/element"] : [`vitral/${fw}`];
964
+ return { entries: [entry, "**/*.html"], include };
965
+ }
32
966
 
33
967
  // src/vite.ts
34
- function vitral(options) {
968
+ function vitral(options = {}) {
35
969
  let outDir = "dist";
36
970
  let root = process.cwd();
37
971
  let pkg = {};
972
+ let manifest;
973
+ let split;
974
+ let entry = options.entry;
975
+ let adapter = "element";
976
+ let framework = "element";
977
+ const entryFile = () => resolve5(root, entry);
978
+ let serve = false;
979
+ let shared = [];
980
+ const dedupe = !!options.dedupe?.length;
981
+ const hooks = dedupeHooks(() => options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entryFile() : ENTRY_ID, () => shared);
38
982
  const scopeName = () => (options.name ?? pkg.name ?? "remote").replace(/[^a-zA-Z0-9_-]/g, "-");
39
983
  return {
40
984
  name: "vitral",
41
- config(_, { mode }) {
985
+ config(user, { mode, command }) {
986
+ entry ??= findEntry(resolve5(user.root ?? process.cwd()));
987
+ if (!entry) throw new Error("[vitral] n\xE3o achei a entrada do remote (src/remote.* ou src/App.*). Use vitral({ entry }).");
42
988
  const rolldown = "rolldownVersion" in this.meta;
43
- const output = rolldown ? { codeSplitting: false } : { inlineDynamicImports: true };
44
989
  return {
45
990
  // Código de biblioteca não tem process.env; React e Vue precisam disso.
46
991
  define: { "process.env.NODE_ENV": JSON.stringify(mode === "development" ? "development" : "production") },
47
992
  server: { cors: true },
993
+ ...command === "serve" && { optimizeDeps: devOptimizeDeps(user.plugins, entry, options.adapter) },
48
994
  preview: { cors: true },
995
+ // O remote não tem index.html: sem isso o Vite só descobre as
996
+ // dependências no primeiro request e recarrega a página do host.
997
+ optimizeDeps: user.optimizeDeps?.entries ? void 0 : { entries: [entry] },
49
998
  build: {
50
999
  // Nomes com hash: cache eterno no CDN. Só o vitral.json muda a cada deploy.
51
- lib: { entry: options.entry, formats: ["es"], fileName: () => "remote-[hash].js", cssFileName: "remote" },
52
- // Um arquivo só: necessário para verificar o hash SRI no host.
53
- rollupOptions: { external: options.shared ?? [], output },
1000
+ lib: { entry: dedupe ? BOOT : options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entry : ENTRY_ID, fileName: () => "remote-[hash].js", cssFileName: "remote" },
1001
+ // Arquivo único (hosts antigos e caminho com blob:) e build dividido (manifesto v2).
1002
+ rollupOptions: { external: options.shared ?? [], output: outputs(rolldown) },
54
1003
  cssCodeSplit: false
55
1004
  }
56
1005
  };
57
1006
  },
58
1007
  configResolved(c) {
59
1008
  root = c.root;
60
- outDir = resolve(c.root, c.build.outDir);
1009
+ framework = detectAdapter(c.plugins);
1010
+ adapter = options.adapter || framework;
1011
+ serve = c.command === "serve";
1012
+ outDir = resolve5(c.root, c.build.outDir);
61
1013
  try {
62
- pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
1014
+ pkg = JSON.parse(readFileSync4(join5(root, "package.json"), "utf8"));
63
1015
  } catch {
64
1016
  }
65
1017
  },
1018
+ async buildStart() {
1019
+ if (dedupe && !serve) shared = await groups(options.dedupe, root, entry, (id, importer) => this.resolve(id, importer, { skipSelf: true }));
1020
+ },
1021
+ // Modo dev: /vitral.json aponta para um módulo com o cliente HMR.
1022
+ configureServer(server) {
1023
+ const scope = options.scopeCss === false ? void 0 : scopeName();
1024
+ serveDevManifest(server, () => devManifest(options.name ?? pkg.name ?? "remote", scope));
1025
+ },
1026
+ // Filtros de hook (Rolldown, Vite 6.3+): os módulos que não são do vitral
1027
+ // nem chegam ao JS. As checagens nos handlers continuam para Vite 5 e 6.0-6.2.
1028
+ resolveId: {
1029
+ order: "pre",
1030
+ filter: { id: [...dedupe ? [dedupeIds(options.dedupe)] : [], ...options.exposes ? [EXPOSES_IDS] : [], /__vitral_entry__\.js$/, DEV_IDS] },
1031
+ handler(id, importer) {
1032
+ const own = dedupe && !serve ? hooks.resolveId.handler(id, importer) : null;
1033
+ if (own) return own;
1034
+ if (options.exposes && resolveExposesId(id)) return resolveExposesId(id);
1035
+ if (id.endsWith(ENTRY_ID)) return VIRTUAL_ENTRY;
1036
+ return resolveDevId(id);
1037
+ }
1038
+ },
1039
+ load: {
1040
+ // Todos os módulos virtuais do vitral: \0vitral... e \0virtual:vitral...
1041
+ filter: { id: /^\x00(virtual:)?vitral/ },
1042
+ handler(id) {
1043
+ const own = dedupe && !serve ? hooks.load(id) : null;
1044
+ if (own != null) return own;
1045
+ const exposed = options.exposes ? loadExposes(id, root, entry, options.exposes, options.adapter === false ? void 0 : ENTRY_ID) : null;
1046
+ if (exposed != null) return exposed;
1047
+ if (id === VIRTUAL_ENTRY) return entryCode(resolve5(root, entry), adapter, scopeName());
1048
+ if (id === VIRTUAL_DEV_ENTRY) return devEntryCode(framework, options.adapter === false ? resolve5(root, entry) : void 0);
1049
+ return loadPreamble(id);
1050
+ }
1051
+ },
1052
+ transform: {
1053
+ filter: { id: DEV_CSS },
1054
+ handler(code, id) {
1055
+ if (serve && options.scopeCss !== false) return scopeDevCss(code, id, scopeName());
1056
+ }
1057
+ },
66
1058
  writeBundle(_, bundle) {
1059
+ if (isSplit(bundle)) return void (split = collect(outDir, bundle));
67
1060
  const files = Object.values(bundle);
68
- const entry = files.find((f) => f.type === "chunk" && f.isEntry);
69
- if (!entry) return;
1061
+ const entry2 = files.find((f) => f.type === "chunk" && f.isEntry);
1062
+ if (!entry2) return;
1063
+ const emit = (file, text, kind = "") => {
1064
+ const hash = createHash2("sha256").update(text).digest("base64url").slice(0, 8);
1065
+ const name = file.replace(/\.css$/, `${kind}-${hash}.css`);
1066
+ writeFileSync2(join5(outDir, name), text);
1067
+ return name;
1068
+ };
1069
+ const shadow = { css: [] };
70
1070
  const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => {
71
- const from = join(outDir, f.fileName);
72
- let text = readFileSync(from, "utf8");
73
- if (options.scopeCss !== false) text = scopeCss(text, scopeName());
74
- const hash = createHash("sha256").update(text).digest("base64url").slice(0, 8);
75
- const name = f.fileName.replace(/\.css$/, `-${hash}.css`);
76
- writeFileSync(join(outDir, name), text);
77
- if (name !== f.fileName) rmSync(from);
1071
+ const from = join5(outDir, f.fileName);
1072
+ const text = transformCss(readFileSync4(from, "utf8"), options, scopeName());
1073
+ const name = emit(f.fileName, text);
1074
+ if (name !== f.fileName) rmSync2(from);
1075
+ const split2 = splitShadowCss(text);
1076
+ shadow.css.push(split2.css === text ? name : emit(f.fileName, split2.css, "-shadow"));
1077
+ if (split2.global) (shadow.global ??= []).push(emit(f.fileName, split2.global, "-global"));
1078
+ if (split2.imports.length) (shadow.imports ??= []).push(...split2.imports);
1079
+ if (split2.rebase) shadow.rebase = true;
78
1080
  return name;
79
1081
  });
80
- const code = readFileSync(join(outDir, entry.fileName));
81
- const manifest = {
1082
+ const code = readFileSync4(join5(outDir, entry2.fileName));
1083
+ manifest = {
82
1084
  name: options.name ?? pkg.name ?? "remote",
83
1085
  version: options.version ?? pkg.version,
84
- entry: entry.fileName,
1086
+ entry: entry2.fileName,
85
1087
  css,
86
- integrity: "sha384-" + createHash("sha384").update(code).digest("base64"),
87
- ...options.scopeCss === false ? {} : { scope: scopeName() }
1088
+ ...css.length ? { shadow } : {},
1089
+ integrity: "sha384-" + createHash2("sha384").update(code).digest("base64"),
1090
+ ...options.scopeCss === false ? {} : { scope: scopeName() },
1091
+ ...options.exposes ? { exposes: Object.keys(exposeKeys(options.exposes)) } : {},
1092
+ ...contractOf(options.contract?.version, shared)
88
1093
  };
89
- writeFileSync(join(outDir, "vitral.json"), JSON.stringify(manifest, null, 2) + "\n");
1094
+ },
1095
+ async closeBundle() {
1096
+ if (!manifest) return;
1097
+ const done = withSplit(manifest, outDir, split, shared);
1098
+ manifest = split = void 0;
1099
+ writeFileSync2(join5(outDir, "vitral.json"), JSON.stringify(done, null, 2) + "\n");
1100
+ const props = options.types === false ? null : await extractProps(root, entryFile());
1101
+ if (props) writeFileSync2(join5(outDir, "vitral.d.ts"), typesFile(done.name, props));
90
1102
  }
91
1103
  };
92
1104
  }
1105
+ function contractOf(version, groups2) {
1106
+ const contract = {
1107
+ ...version && { version },
1108
+ ...groups2.length && { peers: Object.fromEntries(groups2.map((g) => [g.name, g.range])) }
1109
+ };
1110
+ return Object.keys(contract).length ? { contract } : {};
1111
+ }
93
1112
  export {
94
1113
  vitral as default,
95
1114
  vitral