vitral 0.1.0 → 0.2.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.
- package/README.md +250 -217
- package/dist/angular.d.ts +15 -4
- package/dist/angular.js +25 -5
- package/dist/auto.d.ts +2 -0
- package/dist/auto.js +12 -0
- package/dist/chunk-2XF5BKV3.js +190 -0
- package/dist/chunk-6Y3VMWHH.js +181 -0
- package/dist/chunk-DXORSF4X.js +42 -0
- package/dist/chunk-GNPFWISJ.js +80 -0
- package/dist/chunk-HP6QWU6K.js +51 -0
- package/dist/chunk-NCONW6WS.js +606 -0
- package/dist/chunk-PX7PBCCT.js +89 -0
- package/dist/chunk-S5MZT5IT.js +20 -0
- package/dist/chunk-SFL6LTP3.js +56 -0
- package/dist/chunk-UTYAX6MU.js +152 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +88 -0
- package/dist/dedupe-IWFIXRWG.js +81 -0
- package/dist/devtools.d.ts +12 -0
- package/dist/devtools.js +86 -0
- package/dist/element.d.ts +60 -2
- package/dist/element.js +9 -2
- package/dist/errors-KKB8FGCz.d.ts +11 -0
- package/dist/events-DUdjhfps.d.ts +6 -0
- package/dist/expose-53BEJB34.js +14 -0
- package/dist/host-slot-Cz6EiGsB.d.ts +6 -0
- package/dist/iframe.d.ts +28 -0
- package/dist/iframe.js +236 -0
- package/dist/index.d.ts +142 -147
- package/dist/index.js +39 -10
- package/dist/navigate-BRG1WJUM.d.ts +9 -0
- package/dist/overrides-NZAIUGK5.js +15 -0
- package/dist/preact.d.ts +30 -7
- package/dist/preact.js +37 -9
- package/dist/react.d.ts +38 -7
- package/dist/react.js +92 -42
- package/dist/routes.d.ts +56 -0
- package/dist/routes.js +143 -0
- package/dist/shadow-MYRJQLLY.js +72 -0
- package/dist/slot-pB276oPt.d.ts +36 -0
- package/dist/solid.d.ts +29 -6
- package/dist/solid.js +31 -8
- package/dist/sri-BVKZNX5Q.js +114 -0
- package/dist/state-BDdCwc21.d.ts +4 -0
- package/dist/svelte.d.ts +19 -3
- package/dist/svelte.js +10 -4
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +8 -3
- package/dist/types-BV-hUrms.d.ts +265 -0
- package/dist/vite.d.ts +58 -4
- package/dist/vite.js +714 -24
- package/dist/vue.d.ts +79 -7
- package/dist/vue.js +69 -46
- package/package.json +144 -8
- package/dist/chunk-IZK6ITIJ.js +0 -96
- package/dist/chunk-TTL52BF2.js +0 -547
package/dist/vite.js
CHANGED
|
@@ -1,7 +1,267 @@
|
|
|
1
1
|
// src/vite.ts
|
|
2
|
+
import { createHash as createHash2 } from "crypto";
|
|
3
|
+
import { readFileSync as readFileSync3, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
4
|
+
import { join as join4, resolve as resolve4 } 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
|
+
function resolveExposesId(id) {
|
|
20
|
+
return id === EXPOSES_ENTRY || id.endsWith("/" + EXPOSES_ENTRY) || id.endsWith("\\" + EXPOSES_ENTRY) ? ID : null;
|
|
21
|
+
}
|
|
22
|
+
function loadExposes(id, root, entry, exposes, main) {
|
|
23
|
+
if (id !== ID) return null;
|
|
24
|
+
const file = (f) => JSON.stringify(resolve(root, f).replace(/\\/g, "/"));
|
|
25
|
+
const parts = Object.entries(exposeKeys(exposes)).map(([key, f]) => ` ${JSON.stringify(key)}: () => import(${file(f)}),`);
|
|
26
|
+
return [`export * from ${file(entry)}`, `export { default } from ${main ? JSON.stringify(main) : file(entry)}`, `export const exposes = {`, ...parts, `}`, ""].join("\n");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// src/vite/manifest.ts
|
|
2
30
|
import { createHash } from "crypto";
|
|
3
31
|
import { readFileSync, rmSync, writeFileSync } from "fs";
|
|
4
|
-
import { join,
|
|
32
|
+
import { join, posix } from "path";
|
|
33
|
+
var SPLIT = "split/";
|
|
34
|
+
var sri = (file) => "sha384-" + createHash("sha384").update(readFileSync(file)).digest("base64");
|
|
35
|
+
function outputs(rolldown) {
|
|
36
|
+
return [
|
|
37
|
+
{ format: "es", ...rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
|
|
38
|
+
// Os assets saem com o mesmo nome nas duas (o Vite só aceita um padrão).
|
|
39
|
+
{ format: "es", entryFileNames: `${SPLIT}remote-[hash].js`, chunkFileNames: `${SPLIT}[name]-[hash].js` }
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
var isSplit = (bundle) => Object.values(bundle).some((f) => f.type === "chunk" && f.isEntry && f.fileName.startsWith(SPLIT));
|
|
43
|
+
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])})}`;
|
|
44
|
+
function collect(outDir, bundle) {
|
|
45
|
+
for (const f of Object.values(bundle)) if (f.fileName.endsWith(".css")) rmSync(join(outDir, f.fileName), { force: true });
|
|
46
|
+
const chunks = Object.values(bundle).filter((f) => f.type === "chunk");
|
|
47
|
+
const byName = new Map(chunks.map((c) => [c.fileName, c]));
|
|
48
|
+
const deps = (name, seen = /* @__PURE__ */ new Set()) => {
|
|
49
|
+
for (const d of byName.get(name)?.imports ?? []) if (byName.has(d) && !seen.has(d)) seen.add(d), deps(d, seen);
|
|
50
|
+
return seen;
|
|
51
|
+
};
|
|
52
|
+
const live = /* @__PURE__ */ new Map();
|
|
53
|
+
for (const c of chunks) live.set(c.fileName, rewrite(join(outDir, c.fileName), c, byName, deps));
|
|
54
|
+
const entry = chunks.find((c) => c.isEntry).fileName;
|
|
55
|
+
const used = /* @__PURE__ */ new Set([entry]);
|
|
56
|
+
for (const name of used) for (const d of [...deps(name), ...live.get(name)]) used.add(d);
|
|
57
|
+
if (![...used].some((n) => live.get(n).length)) {
|
|
58
|
+
rmSync(join(outDir, SPLIT), { recursive: true, force: true });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
for (const c of chunks) if (!used.has(c.fileName)) rmSync(join(outDir, c.fileName), { force: true });
|
|
62
|
+
const own = {};
|
|
63
|
+
for (const c of chunks) if (used.has(c.fileName) && c.facadeModuleId?.startsWith("\0vitral-own:"))
|
|
64
|
+
own[c.facadeModuleId.slice("\0vitral-own:".length)] = { file: c.fileName, chunks: [...deps(c.fileName)] };
|
|
65
|
+
const soon = deps(entry);
|
|
66
|
+
if (Object.keys(own).length) {
|
|
67
|
+
for (const d of live.get(entry)) if (!Object.values(own).some((o) => o.file === d)) soon.add(d), deps(d, soon);
|
|
68
|
+
}
|
|
69
|
+
soon.delete(entry);
|
|
70
|
+
return { entry, chunks: [...soon], files: [...used], own };
|
|
71
|
+
}
|
|
72
|
+
function rewrite(file, c, byName, deps) {
|
|
73
|
+
const targets = c.dynamicImports.filter((d) => byName.has(d));
|
|
74
|
+
if (!targets.length) return [];
|
|
75
|
+
const dir = posix.dirname(c.fileName);
|
|
76
|
+
const rel = (to) => {
|
|
77
|
+
const r = posix.relative(dir, to);
|
|
78
|
+
return r.startsWith(".") ? r : `./${r}`;
|
|
79
|
+
};
|
|
80
|
+
const done = /* @__PURE__ */ new Set();
|
|
81
|
+
const source = readFileSync(file, "utf8");
|
|
82
|
+
let rest = source;
|
|
83
|
+
let code = source.replace(/\bimport\(\s*(["'`])([^"'`]+)\1\s*\)/g, (all, _q, spec) => {
|
|
84
|
+
const target = posix.join(dir, spec);
|
|
85
|
+
if (!targets.includes(target)) return all;
|
|
86
|
+
done.add(target);
|
|
87
|
+
rest = rest.replace(all, "");
|
|
88
|
+
return `__vitralImport(${JSON.stringify(spec)},${JSON.stringify([...deps(target)].map(rel))})`;
|
|
89
|
+
});
|
|
90
|
+
const missing = targets.filter((t) => !done.has(t) && !c.imports.includes(t) && rest.includes(posix.basename(t)));
|
|
91
|
+
if (missing.length) throw new Error(`vitral: n\xE3o foi poss\xEDvel preparar o import() de ${missing.join(", ")} em ${c.fileName}`);
|
|
92
|
+
if (!done.size) return [];
|
|
93
|
+
const map = /\n\/\/# sourceMappingURL=[^\n]*\n?$/.exec(code);
|
|
94
|
+
const at = map ? map.index : code.length;
|
|
95
|
+
code = `${code.slice(0, at)}
|
|
96
|
+
${helper()}${code.slice(at)}`;
|
|
97
|
+
writeFileSync(file, code);
|
|
98
|
+
return [...done];
|
|
99
|
+
}
|
|
100
|
+
function withSplit(m, outDir, s, groups2 = []) {
|
|
101
|
+
const files = {};
|
|
102
|
+
for (const f of [m.entry, ...m.css ?? [], ...s?.files ?? []]) files[f] = sri(join(outDir, f));
|
|
103
|
+
const dedupe = groups2.filter((g) => s?.own[g.name]).map(({ name, range, version }) => ({ name, range, version, ...s.own[name] }));
|
|
104
|
+
return { ...m, files, ...s && { split: { entry: s.entry, chunks: s.chunks } }, ...dedupe.length && { dedupe } };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/vite/dedupe.ts
|
|
108
|
+
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
109
|
+
import { dirname, join as join2, resolve as resolve2 } from "path";
|
|
110
|
+
import { pathToFileURL } from "url";
|
|
111
|
+
var REACT = ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "react/jsx-dev-runtime", "react/compiler-runtime"];
|
|
112
|
+
var BOOT = "virtual:vitral-boot";
|
|
113
|
+
var DEPS = "\0vitral-deps";
|
|
114
|
+
var OWN = "\0vitral-own:";
|
|
115
|
+
var SHIM = "\0vitral-shim:";
|
|
116
|
+
var pkgOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
117
|
+
var groupOf = (spec) => REACT.includes(spec) || pkgOf(spec) === "scheduler" ? "react" : pkgOf(spec);
|
|
118
|
+
var ident = /^[A-Za-z_$][\w$]*$/;
|
|
119
|
+
function versionOf(file, pkg) {
|
|
120
|
+
for (let dir = dirname(file); dir !== dirname(dir); dir = dirname(dir)) {
|
|
121
|
+
const json = join2(dir, "package.json");
|
|
122
|
+
if (!existsSync(json)) continue;
|
|
123
|
+
const data = JSON.parse(readFileSync2(json, "utf8"));
|
|
124
|
+
if (data.name === pkg) return data.version;
|
|
125
|
+
}
|
|
126
|
+
throw new Error(`vitral: vers\xE3o de ${pkg} n\xE3o encontrada`);
|
|
127
|
+
}
|
|
128
|
+
async function groups(list, root, entry, resolveId) {
|
|
129
|
+
const importer = resolve2(root, entry);
|
|
130
|
+
const byName = /* @__PURE__ */ new Map();
|
|
131
|
+
for (const spec of list) {
|
|
132
|
+
const g = groupOf(spec);
|
|
133
|
+
byName.set(g, [.../* @__PURE__ */ new Set([...byName.get(g) ?? [], ...g === "react" ? REACT : [spec]])]);
|
|
134
|
+
}
|
|
135
|
+
const out = [];
|
|
136
|
+
for (const [name, specs] of byName) {
|
|
137
|
+
const group = { name, range: "", version: "", keys: [], names: {}, pkgs: name === "react" ? ["react", "react-dom", "scheduler"] : [name] };
|
|
138
|
+
for (const spec of specs) {
|
|
139
|
+
const found = await resolveId(spec, importer);
|
|
140
|
+
if (!found) {
|
|
141
|
+
if (spec === name) throw new Error(`vitral: dedupe: ${spec} n\xE3o est\xE1 instalado`);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const mod = await import(pathToFileURL(found.id.split("?")[0]).href);
|
|
145
|
+
const extra = mod.default && typeof mod.default === "object" ? Object.keys(mod.default) : [];
|
|
146
|
+
group.names[spec] = [.../* @__PURE__ */ new Set([...Object.keys(mod), ...extra])].filter((n) => n !== "default" && ident.test(n));
|
|
147
|
+
group.keys.push(spec);
|
|
148
|
+
if (spec === name) group.version = versionOf(found.id, name);
|
|
149
|
+
}
|
|
150
|
+
group.range = name === "svelte" || name.startsWith("@angular/") ? group.version : `^${group.version}`;
|
|
151
|
+
out.push(group);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
function dedupeHooks(entry, getGroups) {
|
|
156
|
+
const keyOf = (id) => getGroups().find((g) => g.keys.includes(id));
|
|
157
|
+
return {
|
|
158
|
+
resolveId: {
|
|
159
|
+
order: "pre",
|
|
160
|
+
handler(id, importer) {
|
|
161
|
+
if (id.endsWith(BOOT)) return `\0${BOOT}`;
|
|
162
|
+
if (id === DEPS || id.startsWith(OWN) || id.startsWith(SHIM)) return id;
|
|
163
|
+
const g = keyOf(id);
|
|
164
|
+
if (!g || !importer || importer.startsWith(OWN)) return null;
|
|
165
|
+
const norm = importer.replace(/\\/g, "/");
|
|
166
|
+
if (g.pkgs.some((p) => norm.includes(`/node_modules/${p}/`))) return null;
|
|
167
|
+
return SHIM + id;
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
load(id) {
|
|
171
|
+
if (id === `\0${BOOT}`) return boot(entry(), getGroups());
|
|
172
|
+
if (id === DEPS) return "export const deps = {}";
|
|
173
|
+
if (id.startsWith(OWN)) {
|
|
174
|
+
const g = getGroups().find((x) => x.name === id.slice(OWN.length));
|
|
175
|
+
return g.keys.map((k, i) => `import * as m${i} from ${JSON.stringify(k)}`).join("\n") + `
|
|
176
|
+
export default {${g.keys.map((k, i) => `${JSON.stringify(k)}: m${i}`).join(", ")}}
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
if (id.startsWith(SHIM)) {
|
|
180
|
+
const spec = id.slice(SHIM.length);
|
|
181
|
+
const names = keyOf(spec).names[spec];
|
|
182
|
+
return `import { deps } from ${JSON.stringify(DEPS)}
|
|
183
|
+
const m = deps[${JSON.stringify(spec)}]
|
|
184
|
+
export default m.default ?? m
|
|
185
|
+
` + (names.length ? `export const { ${names.join(", ")} } = m
|
|
186
|
+
` : "");
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function boot(entry, groups2) {
|
|
193
|
+
const calls = groups2.map(
|
|
194
|
+
(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))`
|
|
195
|
+
);
|
|
196
|
+
return `const { deps } = await import(${JSON.stringify(DEPS)})
|
|
197
|
+
const p = globalThis[Symbol.for("vitral")]
|
|
198
|
+
const shared = !!(p && p.dedupe) && /\\/split\\/[^/]*$/.test(import.meta.url)
|
|
199
|
+
async function need(name, range, version, keys, load) {
|
|
200
|
+
let m = shared && (await p.dedupe(name, range, { version, load }))
|
|
201
|
+
if (!m || keys.some((k) => !(k in m))) m = await load()
|
|
202
|
+
Object.assign(deps, m)
|
|
203
|
+
}
|
|
204
|
+
await Promise.all([${calls.join(", ")}])
|
|
205
|
+
const remote = await import(${JSON.stringify(entry)})
|
|
206
|
+
export default remote.default
|
|
207
|
+
`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/css-build.ts
|
|
211
|
+
import postcss2 from "postcss";
|
|
212
|
+
|
|
213
|
+
// src/css-layers.ts
|
|
214
|
+
function flattenLayers(root) {
|
|
215
|
+
flatten(root);
|
|
216
|
+
}
|
|
217
|
+
function flatten(container) {
|
|
218
|
+
const head = [];
|
|
219
|
+
const layers = /* @__PURE__ */ new Map();
|
|
220
|
+
const rest = [];
|
|
221
|
+
let anonymous = 0;
|
|
222
|
+
const layer = (name) => {
|
|
223
|
+
let nodes = layers.get(name);
|
|
224
|
+
if (!nodes) layers.set(name, nodes = []);
|
|
225
|
+
return nodes;
|
|
226
|
+
};
|
|
227
|
+
for (const node of [...container.nodes]) {
|
|
228
|
+
const at = node.type === "atrule" ? node : null;
|
|
229
|
+
if (at?.name.toLowerCase() === "layer") {
|
|
230
|
+
if (!at.nodes) {
|
|
231
|
+
for (const name of at.params.split(",")) layer(name.trim());
|
|
232
|
+
} else {
|
|
233
|
+
flatten(at);
|
|
234
|
+
layer(at.params.trim() || `\0${anonymous++}`).push(...at.nodes);
|
|
235
|
+
}
|
|
236
|
+
} else if (!layers.size && !rest.length && (node.type === "comment" || /^(?:charset|import)$/i.test(at?.name ?? ""))) {
|
|
237
|
+
head.push(node);
|
|
238
|
+
} else {
|
|
239
|
+
if (at?.nodes) flatten(at);
|
|
240
|
+
rest.push(node);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (!layers.size) return;
|
|
244
|
+
container.removeAll();
|
|
245
|
+
container.append(...head, ...[...layers.values()].flat(), ...rest);
|
|
246
|
+
}
|
|
247
|
+
function renameRegisteredProperties(root, scope) {
|
|
248
|
+
const names = [];
|
|
249
|
+
root.walkAtRules(/^property$/i, (rule) => {
|
|
250
|
+
const name = rule.params.trim();
|
|
251
|
+
if (name.startsWith("--tw-")) names.push(name.slice(5).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&"));
|
|
252
|
+
});
|
|
253
|
+
if (!names.length) return;
|
|
254
|
+
const re = new RegExp(`(?<![\\w-])--tw-(${names.join("|")})(?![\\w-])`, "g");
|
|
255
|
+
const to = `--tw-${scope}-$1`;
|
|
256
|
+
root.walk((node) => {
|
|
257
|
+
if (node.type === "decl") {
|
|
258
|
+
node.prop = node.prop.replace(re, to);
|
|
259
|
+
node.value = node.value.replace(re, to);
|
|
260
|
+
} else if (node.type === "atrule") {
|
|
261
|
+
node.params = node.params.replace(re, to);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
5
265
|
|
|
6
266
|
// src/css-scope.ts
|
|
7
267
|
import postcss from "postcss";
|
|
@@ -16,8 +276,12 @@ function scopeSelector(selector, scope) {
|
|
|
16
276
|
return `${scope} ${s}`;
|
|
17
277
|
}
|
|
18
278
|
function scopeCss(css, scopeName) {
|
|
19
|
-
const scope = `[data-vitral-scope="${scopeName}"]`;
|
|
20
279
|
const root = postcss.parse(css);
|
|
280
|
+
scopeRoot(root, scopeName);
|
|
281
|
+
return root.toString();
|
|
282
|
+
}
|
|
283
|
+
function scopeRoot(root, scopeName) {
|
|
284
|
+
const scope = `[data-vitral-scope="${scopeName}"]`;
|
|
21
285
|
root.walkRules((rule) => {
|
|
22
286
|
let p = rule.parent;
|
|
23
287
|
while (p && p.type !== "root") {
|
|
@@ -27,66 +291,492 @@ function scopeCss(css, scopeName) {
|
|
|
27
291
|
}
|
|
28
292
|
rule.selectors = rule.selectors.map((sel) => scopeSelector(sel, scope));
|
|
29
293
|
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/css-theme.ts
|
|
297
|
+
var GLOBAL2 = /^(?::root|:host|html|body)([.:[#][^\s>+~]*)?$/i;
|
|
298
|
+
var CONDITIONAL = /^(?:media|supports|container|scope|starting-style)$/i;
|
|
299
|
+
function hostTheme(root) {
|
|
300
|
+
const theme = /* @__PURE__ */ new Map();
|
|
301
|
+
root.walkRules((rule) => {
|
|
302
|
+
if (!rule.selectors.every((s) => GLOBAL2.test(s.trim()))) return;
|
|
303
|
+
const base = rule.selectors.every((s) => !GLOBAL2.exec(s.trim())[1]) && !insideConditional(rule);
|
|
304
|
+
rule.each((node) => {
|
|
305
|
+
if (node.type !== "decl" || !node.prop.startsWith("--")) return;
|
|
306
|
+
if (base) theme.set(node.prop, node.value.trim());
|
|
307
|
+
node.remove();
|
|
308
|
+
});
|
|
309
|
+
if (!rule.nodes.length) rule.remove();
|
|
310
|
+
});
|
|
311
|
+
if (!theme.size) return;
|
|
312
|
+
root.walkDecls((decl) => {
|
|
313
|
+
if (/var\(/i.test(decl.value)) decl.value = withFallbacks(decl.value, theme, /* @__PURE__ */ new Set());
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
function insideConditional(rule) {
|
|
317
|
+
for (let p = rule.parent; p && p.type !== "root"; p = p.parent) {
|
|
318
|
+
if (p.type === "atrule" && CONDITIONAL.test(p.name)) return true;
|
|
319
|
+
}
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
function withFallbacks(value, theme, seen) {
|
|
323
|
+
return mapVars(value, (name, fallback) => {
|
|
324
|
+
const own = theme.get(name);
|
|
325
|
+
if (own !== void 0 && !seen.has(name)) {
|
|
326
|
+
return `var(${name}, ${withFallbacks(own, theme, new Set(seen).add(name))})`;
|
|
327
|
+
}
|
|
328
|
+
return fallback === void 0 ? `var(${name})` : `var(${name},${withFallbacks(fallback, theme, seen)})`;
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function mapVars(value, fn) {
|
|
332
|
+
let out = "";
|
|
333
|
+
let i = 0;
|
|
334
|
+
for (; ; ) {
|
|
335
|
+
const start = findVar(value, i);
|
|
336
|
+
if (start < 0) return out + value.slice(i);
|
|
337
|
+
const open = start + 4;
|
|
338
|
+
const close = matchParen(value, open);
|
|
339
|
+
if (close < 0) return out + value.slice(i);
|
|
340
|
+
const inner = value.slice(open, close);
|
|
341
|
+
const comma = topLevelComma(inner);
|
|
342
|
+
const name = (comma < 0 ? inner : inner.slice(0, comma)).trim();
|
|
343
|
+
out += value.slice(i, start) + fn(name, comma < 0 ? void 0 : inner.slice(comma + 1));
|
|
344
|
+
i = close + 1;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function findVar(value, from) {
|
|
348
|
+
const re = /var\(/gi;
|
|
349
|
+
re.lastIndex = from;
|
|
350
|
+
for (let m = re.exec(value); m; m = re.exec(value)) {
|
|
351
|
+
if (!/[\w-]/.test(value[m.index - 1] ?? "")) return m.index;
|
|
352
|
+
}
|
|
353
|
+
return -1;
|
|
354
|
+
}
|
|
355
|
+
function matchParen(s, open) {
|
|
356
|
+
let depth = 1;
|
|
357
|
+
let quote = "";
|
|
358
|
+
for (let i = open; i < s.length; i++) {
|
|
359
|
+
const c = s[i];
|
|
360
|
+
if (c === "\\") i++;
|
|
361
|
+
else if (quote) quote = c === quote ? "" : quote;
|
|
362
|
+
else if (c === '"' || c === "'") quote = c;
|
|
363
|
+
else if (c === "(") depth++;
|
|
364
|
+
else if (c === ")" && !--depth) return i;
|
|
365
|
+
}
|
|
366
|
+
return -1;
|
|
367
|
+
}
|
|
368
|
+
function topLevelComma(s) {
|
|
369
|
+
let depth = 0;
|
|
370
|
+
let quote = "";
|
|
371
|
+
for (let i = 0; i < s.length; i++) {
|
|
372
|
+
const c = s[i];
|
|
373
|
+
if (c === "\\") i++;
|
|
374
|
+
else if (quote) quote = c === quote ? "" : quote;
|
|
375
|
+
else if (c === '"' || c === "'") quote = c;
|
|
376
|
+
else if (c === "(") depth++;
|
|
377
|
+
else if (c === ")") depth--;
|
|
378
|
+
else if (c === "," && !depth) return i;
|
|
379
|
+
}
|
|
380
|
+
return -1;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/css-build.ts
|
|
384
|
+
function transformCss(css, options, scope) {
|
|
385
|
+
const root = postcss2.parse(css);
|
|
386
|
+
if (options.theme === "host") hostTheme(root);
|
|
387
|
+
if (options.layers === "flatten") flattenLayers(root);
|
|
388
|
+
if (options.renameRegisteredProperties) renameRegisteredProperties(root, scope);
|
|
389
|
+
if (options.scopeCss !== false) scopeRoot(root, scope);
|
|
30
390
|
return root.toString();
|
|
31
391
|
}
|
|
32
392
|
|
|
393
|
+
// src/vite/adapter.ts
|
|
394
|
+
import { existsSync as existsSync2 } from "fs";
|
|
395
|
+
import { resolve as resolve3 } from "path";
|
|
396
|
+
var PLUGINS = [
|
|
397
|
+
[/^(preact:|prefresh$)/, "preact"],
|
|
398
|
+
[/^vite:react/, "react"],
|
|
399
|
+
[/^vite:vue$/, "vue"],
|
|
400
|
+
[/^vite-plugin-svelte/, "svelte"],
|
|
401
|
+
[/^solid$/, "solid"],
|
|
402
|
+
[/^@analogjs\/vite-plugin-angular$/, "angular"]
|
|
403
|
+
];
|
|
404
|
+
function detectAdapter(plugins) {
|
|
405
|
+
for (const [re, adapter] of PLUGINS) if (plugins.some((p) => re.test(p.name))) return adapter;
|
|
406
|
+
return "element";
|
|
407
|
+
}
|
|
408
|
+
var WRAP = {
|
|
409
|
+
react: ["vitral/react", "reactRemote"],
|
|
410
|
+
vue: ["vitral/vue", "vueRemote"],
|
|
411
|
+
svelte: ["vitral/svelte", "svelteRemote"],
|
|
412
|
+
solid: ["vitral/solid", "solidRemote"],
|
|
413
|
+
preact: ["vitral/preact", "preactRemote"],
|
|
414
|
+
angular: ["vitral/angular", "angularRemote"]
|
|
415
|
+
};
|
|
416
|
+
var ENTRY_ID = "__vitral_entry__.js";
|
|
417
|
+
var VIRTUAL_ENTRY = "\0vitral:entry";
|
|
418
|
+
function entryCode(file, adapter, scope) {
|
|
419
|
+
const head = `import * as m from ${JSON.stringify(file)}
|
|
420
|
+
const c = m.default ?? m
|
|
421
|
+
`;
|
|
422
|
+
if (adapter !== "element") {
|
|
423
|
+
const [from, fn] = WRAP[adapter];
|
|
424
|
+
return `${head}import { ${fn} as wrap } from '${from}'
|
|
425
|
+
export default typeof c?.mount === 'function' ? c : wrap(c)
|
|
426
|
+
`;
|
|
427
|
+
}
|
|
428
|
+
return `${head}import { elementRemote } from 'vitral/element'
|
|
429
|
+
import { component } from 'vitral'
|
|
430
|
+
function wrap(c) {
|
|
431
|
+
if (typeof c === 'function' && typeof HTMLElement !== 'undefined' && c.prototype instanceof HTMLElement) {
|
|
432
|
+
const base = ${JSON.stringify(`${scope}-remote`.toLowerCase().replace(/^[^a-z]+/, "x-"))}
|
|
433
|
+
let tag = customElements.getName?.(c) || base
|
|
434
|
+
// Uma tag n\xE3o aceita outra classe: no HMR, a classe nova ganha tag nova.
|
|
435
|
+
for (let n = 2; customElements.get(tag) && customElements.get(tag) !== c; n++) tag = base + '-' + n
|
|
436
|
+
return elementRemote(tag, () => customElements.get(tag) || customElements.define(tag, c))
|
|
437
|
+
}
|
|
438
|
+
if (typeof c === 'function') return component(c)
|
|
439
|
+
throw new Error('[vitral] o export default n\xE3o \xE9 um remote: exporte um componente, uma fun\xE7\xE3o ou um objeto com mount()')
|
|
440
|
+
}
|
|
441
|
+
export default typeof c?.mount === 'function' ? c : wrap(c)
|
|
442
|
+
`;
|
|
443
|
+
}
|
|
444
|
+
var CANDIDATES = ["src/remote", "src/App", "src/app"];
|
|
445
|
+
var EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".vue", ".svelte"];
|
|
446
|
+
function findEntry(root) {
|
|
447
|
+
for (const base of CANDIDATES) {
|
|
448
|
+
for (const ext of EXTENSIONS) if (existsSync2(resolve3(root, base + ext))) return base + ext;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// src/vite/types.ts
|
|
453
|
+
import { createRequire } from "module";
|
|
454
|
+
import { join as join3 } from "path";
|
|
455
|
+
function typesFile(name, props) {
|
|
456
|
+
return `// Props do remote ${JSON.stringify(name)}, geradas pelo vitral. N\xE3o edite.
|
|
457
|
+
export type Props = ${props}
|
|
458
|
+
`;
|
|
459
|
+
}
|
|
460
|
+
async function loadTs(root) {
|
|
461
|
+
try {
|
|
462
|
+
return createRequire(join3(root, "package.json"))("typescript");
|
|
463
|
+
} catch {
|
|
464
|
+
try {
|
|
465
|
+
return (await import("typescript")).default;
|
|
466
|
+
} catch {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
async function extractProps(root, file) {
|
|
472
|
+
if (!/\.[cm]?[jt]sx?$/.test(file)) return null;
|
|
473
|
+
const ts = await loadTs(root);
|
|
474
|
+
if (!ts) return null;
|
|
475
|
+
const configPath = ts.findConfigFile(root, ts.sys.fileExists);
|
|
476
|
+
const base = configPath ? ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, ts.sys.readFile).config, ts.sys, root).options : {};
|
|
477
|
+
const options = {
|
|
478
|
+
target: ts.ScriptTarget.ES2022,
|
|
479
|
+
module: ts.ModuleKind.ESNext,
|
|
480
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
481
|
+
jsx: ts.JsxEmit.Preserve,
|
|
482
|
+
strict: true,
|
|
483
|
+
...base,
|
|
484
|
+
allowJs: true,
|
|
485
|
+
skipLibCheck: true,
|
|
486
|
+
noEmit: true
|
|
487
|
+
};
|
|
488
|
+
const program = ts.createProgram([file], options);
|
|
489
|
+
const checker = program.getTypeChecker();
|
|
490
|
+
const source = program.getSourceFile(file);
|
|
491
|
+
const moduleSymbol = source && checker.getSymbolAtLocation(source);
|
|
492
|
+
let symbol = moduleSymbol && checker.getExportsOfModule(moduleSymbol).find((s) => s.escapedName === "default");
|
|
493
|
+
if (!source || !symbol) return null;
|
|
494
|
+
if (symbol.flags & ts.SymbolFlags.Alias) symbol = checker.getAliasedSymbol(symbol);
|
|
495
|
+
const type = checker.getTypeOfSymbolAtLocation(symbol, source);
|
|
496
|
+
const props = propsOf(checker, type, source);
|
|
497
|
+
return props ? new Printer(ts, checker, program).print(props, 0, true) : "Record<string, unknown>";
|
|
498
|
+
}
|
|
499
|
+
function propsOf(checker, type, at) {
|
|
500
|
+
const param = (t, i) => {
|
|
501
|
+
const p = t.getCallSignatures()[0]?.parameters[i];
|
|
502
|
+
return p && checker.getTypeOfSymbolAtLocation(p, at);
|
|
503
|
+
};
|
|
504
|
+
const mount = type.getProperty("mount");
|
|
505
|
+
if (mount) return param(checker.getTypeOfSymbolAtLocation(mount, at), 1);
|
|
506
|
+
if (type.getCallSignatures().length) return param(type, 0);
|
|
507
|
+
const ctor = type.getConstructSignatures()[0];
|
|
508
|
+
const props = ctor?.getReturnType().getProperty("props");
|
|
509
|
+
return props && checker.getTypeOfSymbolAtLocation(props, at);
|
|
510
|
+
}
|
|
511
|
+
var Printer = class {
|
|
512
|
+
constructor(ts, checker, program) {
|
|
513
|
+
this.ts = ts;
|
|
514
|
+
this.checker = checker;
|
|
515
|
+
this.program = program;
|
|
516
|
+
this.seen = /* @__PURE__ */ new Set();
|
|
517
|
+
}
|
|
518
|
+
/** Declarado na lib padrão (Date, Map…): vale em qualquer projeto pelo nome. */
|
|
519
|
+
fromLib(type) {
|
|
520
|
+
const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
|
|
521
|
+
return !!decl && this.program.isSourceFileDefaultLibrary(decl.getSourceFile());
|
|
522
|
+
}
|
|
523
|
+
fromPackage(type) {
|
|
524
|
+
const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
|
|
525
|
+
return !!decl && /[/\\]node_modules[/\\]/.test(decl.getSourceFile().fileName);
|
|
526
|
+
}
|
|
527
|
+
print(type, depth, top = false) {
|
|
528
|
+
const { ts, checker } = this;
|
|
529
|
+
const f = type.flags;
|
|
530
|
+
if (f & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return "unknown";
|
|
531
|
+
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)) {
|
|
532
|
+
return checker.typeToString(type);
|
|
533
|
+
}
|
|
534
|
+
if (type.isUnion()) {
|
|
535
|
+
const parts = [...new Set(type.types.map((t) => this.print(t, depth)))];
|
|
536
|
+
if (parts.includes("true") && parts.includes("false")) parts.splice(parts.indexOf("true"), 1, "boolean"), parts.splice(parts.indexOf("false"), 1);
|
|
537
|
+
return parts.join(" | ");
|
|
538
|
+
}
|
|
539
|
+
if (type.isIntersection()) return type.types.map((t) => this.wrap(t, depth)).join(" & ");
|
|
540
|
+
if (depth > 6 || this.seen.has(type)) return "unknown";
|
|
541
|
+
if (checker.isArrayType(type)) return `Array<${this.print(checker.getTypeArguments(type)[0], depth + 1)}>`;
|
|
542
|
+
if (checker.isTupleType(type)) return `[${checker.getTypeArguments(type).map((t) => this.print(t, depth + 1)).join(", ")}]`;
|
|
543
|
+
if (this.fromLib(type)) {
|
|
544
|
+
const args = type.aliasTypeArguments ?? (type.objectFlags & ts.ObjectFlags.Reference ? checker.getTypeArguments(type) : []);
|
|
545
|
+
const name = (type.aliasSymbol ?? type.getSymbol()).name;
|
|
546
|
+
return args.length ? `${name}<${args.map((t) => this.print(t, depth + 1)).join(", ")}>` : checker.typeToString(type);
|
|
547
|
+
}
|
|
548
|
+
if (this.fromPackage(type)) return "unknown";
|
|
549
|
+
this.seen.add(type);
|
|
550
|
+
try {
|
|
551
|
+
const calls = type.getCallSignatures();
|
|
552
|
+
const props = checker.getPropertiesOfType(type).filter((p) => !(top && p.name === "vitral"));
|
|
553
|
+
if (calls.length && !props.length) return this.signature(calls[0], depth);
|
|
554
|
+
const fields = props.map((p) => {
|
|
555
|
+
const optional = p.flags & ts.SymbolFlags.Optional ? "?" : "";
|
|
556
|
+
const key = /^[A-Za-z_$][\w$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
|
|
557
|
+
const t = checker.getTypeOfSymbol(p);
|
|
558
|
+
return `${key}${optional}: ${this.print(optional ? checker.getNonNullableType(t) : t, depth + 1)}`;
|
|
559
|
+
});
|
|
560
|
+
const index = type.getStringIndexType();
|
|
561
|
+
if (index) fields.push(`[key: string]: ${this.print(index, depth + 1)}`);
|
|
562
|
+
for (const c of calls) fields.push(this.signature(c, depth).replace(" =>", ":"));
|
|
563
|
+
return fields.length ? `{ ${fields.join("; ")} }` : "{}";
|
|
564
|
+
} finally {
|
|
565
|
+
this.seen.delete(type);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
wrap(type, depth) {
|
|
569
|
+
const s = this.print(type, depth);
|
|
570
|
+
return type.isUnion() ? `(${s})` : s;
|
|
571
|
+
}
|
|
572
|
+
signature(sig, depth) {
|
|
573
|
+
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)}`);
|
|
574
|
+
return `(${params.join(", ")}) => ${this.print(sig.getReturnType(), depth + 1)}`;
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
// src/vite/dev.ts
|
|
579
|
+
var DEV_ENTRY = "@vitral/entry.js";
|
|
580
|
+
var VIRTUAL_DEV_ENTRY = "\0vitral:dev-entry";
|
|
581
|
+
var PREAMBLE_ID = "virtual:vitral-react-preamble";
|
|
582
|
+
var REACT_PREAMBLE = `import { injectIntoGlobalHook } from '/@react-refresh'
|
|
583
|
+
injectIntoGlobalHook(window)
|
|
584
|
+
window.$RefreshReg$ ??= () => {}
|
|
585
|
+
window.$RefreshSig$ ??= () => (type) => type
|
|
586
|
+
window.__vite_plugin_react_preamble_installed__ = true
|
|
587
|
+
`;
|
|
588
|
+
function devEntryCode(framework, raw) {
|
|
589
|
+
const preamble = framework === "react" ? `import '${PREAMBLE_ID}'
|
|
590
|
+
` : "";
|
|
591
|
+
const from = raw ? JSON.stringify(raw) : `'${ENTRY_ID}'`;
|
|
592
|
+
return `import '/@vite/client'
|
|
593
|
+
${preamble}import * as first from ${from}
|
|
594
|
+
let mod = first.default ?? first
|
|
595
|
+
const live = new Set()
|
|
596
|
+
export default {
|
|
597
|
+
async mount(el, props, ctx) {
|
|
598
|
+
const i = { props, handle: await mod.mount(el, props, ctx) }
|
|
599
|
+
i.remount = async () => {
|
|
600
|
+
i.handle.unmount()
|
|
601
|
+
el.replaceChildren()
|
|
602
|
+
i.handle = await mod.mount(el, i.props, ctx)
|
|
603
|
+
}
|
|
604
|
+
live.add(i)
|
|
605
|
+
return {
|
|
606
|
+
update(next) {
|
|
607
|
+
i.props = next
|
|
608
|
+
i.handle.update?.(next)
|
|
609
|
+
},
|
|
610
|
+
unmount() {
|
|
611
|
+
live.delete(i)
|
|
612
|
+
i.handle.unmount()
|
|
613
|
+
},
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
}
|
|
617
|
+
if (import.meta.hot) {
|
|
618
|
+
import.meta.hot.accept(${from}, (next) => {
|
|
619
|
+
if (!next) return import.meta.hot.invalidate()
|
|
620
|
+
mod = next.default ?? next
|
|
621
|
+
for (const i of live) i.remount().catch((e) => console.error('[vitral] falha ao remontar depois da edi\xE7\xE3o', e))
|
|
622
|
+
})
|
|
623
|
+
}
|
|
624
|
+
`;
|
|
625
|
+
}
|
|
626
|
+
function resolveDevId(id) {
|
|
627
|
+
if (id === PREAMBLE_ID) return "\0" + PREAMBLE_ID;
|
|
628
|
+
if (id.endsWith("/" + DEV_ENTRY)) return VIRTUAL_DEV_ENTRY;
|
|
629
|
+
}
|
|
630
|
+
function loadPreamble(id) {
|
|
631
|
+
if (id === "\0" + PREAMBLE_ID) return REACT_PREAMBLE;
|
|
632
|
+
}
|
|
633
|
+
function devManifest(name, scope) {
|
|
634
|
+
return { name, entry: DEV_ENTRY, css: [], ...scope ? { scope } : {} };
|
|
635
|
+
}
|
|
636
|
+
function scopeDevCss(code, id, scope) {
|
|
637
|
+
if (!/\.(css|less|sass|scss|styl|stylus|pcss|postcss|sss)(\?|$)/.test(id) || /[?&](raw|url|inline)\b/.test(id)) return;
|
|
638
|
+
return scopeCss(code, scope);
|
|
639
|
+
}
|
|
640
|
+
function serveDevManifest(server, manifest) {
|
|
641
|
+
const path = `${server.config.base.replace(/\/?$/, "/")}vitral.json`;
|
|
642
|
+
server.httpServer?.once("listening", () => {
|
|
643
|
+
const address = server.httpServer.address();
|
|
644
|
+
if (!server.config.server.origin && address && typeof address === "object") {
|
|
645
|
+
const protocol = server.config.server.https ? "https" : "http";
|
|
646
|
+
server.config.server.origin = `${protocol}://localhost:${address.port}`;
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
server.middlewares.use((req, res, next) => {
|
|
650
|
+
if (req.url?.split("?")[0] !== path) return next();
|
|
651
|
+
res.writeHead(200, {
|
|
652
|
+
"content-type": "application/json",
|
|
653
|
+
"cache-control": "no-store",
|
|
654
|
+
"access-control-allow-origin": "*"
|
|
655
|
+
});
|
|
656
|
+
res.end(JSON.stringify(manifest(), null, 2));
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
function devOptimizeDeps(plugins, entry, adapter) {
|
|
660
|
+
const named = [plugins].flat(Infinity).filter((p) => typeof p?.name === "string");
|
|
661
|
+
const fw = adapter === false ? null : adapter || detectAdapter(named);
|
|
662
|
+
const include = fw === null ? [] : fw === "element" ? ["vitral", "vitral/element"] : [`vitral/${fw}`];
|
|
663
|
+
return { entries: [entry, "**/*.html"], include };
|
|
664
|
+
}
|
|
665
|
+
|
|
33
666
|
// src/vite.ts
|
|
34
|
-
function vitral(options) {
|
|
667
|
+
function vitral(options = {}) {
|
|
35
668
|
let outDir = "dist";
|
|
36
669
|
let root = process.cwd();
|
|
37
670
|
let pkg = {};
|
|
671
|
+
let manifest;
|
|
672
|
+
let split;
|
|
673
|
+
let entry = options.entry;
|
|
674
|
+
let adapter = "element";
|
|
675
|
+
let framework = "element";
|
|
676
|
+
const entryFile = () => resolve4(root, entry);
|
|
677
|
+
let serve = false;
|
|
678
|
+
let shared = [];
|
|
679
|
+
const dedupe = !!options.dedupe?.length;
|
|
680
|
+
const hooks = dedupeHooks(() => options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entryFile() : ENTRY_ID, () => shared);
|
|
38
681
|
const scopeName = () => (options.name ?? pkg.name ?? "remote").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
39
682
|
return {
|
|
40
683
|
name: "vitral",
|
|
41
|
-
config(
|
|
684
|
+
config(user, { mode, command }) {
|
|
685
|
+
entry ??= findEntry(resolve4(user.root ?? process.cwd()));
|
|
686
|
+
if (!entry) throw new Error("[vitral] n\xE3o achei a entrada do remote (src/remote.* ou src/App.*). Use vitral({ entry }).");
|
|
42
687
|
const rolldown = "rolldownVersion" in this.meta;
|
|
43
|
-
const output = rolldown ? { codeSplitting: false } : { inlineDynamicImports: true };
|
|
44
688
|
return {
|
|
45
689
|
// Código de biblioteca não tem process.env; React e Vue precisam disso.
|
|
46
690
|
define: { "process.env.NODE_ENV": JSON.stringify(mode === "development" ? "development" : "production") },
|
|
47
691
|
server: { cors: true },
|
|
692
|
+
...command === "serve" && { optimizeDeps: devOptimizeDeps(user.plugins, entry, options.adapter) },
|
|
48
693
|
preview: { cors: true },
|
|
694
|
+
// O remote não tem index.html: sem isso o Vite só descobre as
|
|
695
|
+
// dependências no primeiro request e recarrega a página do host.
|
|
696
|
+
optimizeDeps: user.optimizeDeps?.entries ? void 0 : { entries: [entry] },
|
|
49
697
|
build: {
|
|
50
698
|
// Nomes com hash: cache eterno no CDN. Só o vitral.json muda a cada deploy.
|
|
51
|
-
lib: { entry: options.entry
|
|
52
|
-
//
|
|
53
|
-
rollupOptions: { external: options.shared ?? [], output },
|
|
699
|
+
lib: { entry: dedupe ? BOOT : options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entry : ENTRY_ID, fileName: () => "remote-[hash].js", cssFileName: "remote" },
|
|
700
|
+
// Arquivo único (hosts antigos e caminho com blob:) e build dividido (manifesto v2).
|
|
701
|
+
rollupOptions: { external: options.shared ?? [], output: outputs(rolldown) },
|
|
54
702
|
cssCodeSplit: false
|
|
55
703
|
}
|
|
56
704
|
};
|
|
57
705
|
},
|
|
58
706
|
configResolved(c) {
|
|
59
707
|
root = c.root;
|
|
60
|
-
|
|
708
|
+
framework = detectAdapter(c.plugins);
|
|
709
|
+
adapter = options.adapter || framework;
|
|
710
|
+
serve = c.command === "serve";
|
|
711
|
+
outDir = resolve4(c.root, c.build.outDir);
|
|
61
712
|
try {
|
|
62
|
-
pkg = JSON.parse(
|
|
713
|
+
pkg = JSON.parse(readFileSync3(join4(root, "package.json"), "utf8"));
|
|
63
714
|
} catch {
|
|
64
715
|
}
|
|
65
716
|
},
|
|
717
|
+
async buildStart() {
|
|
718
|
+
if (dedupe && !serve) shared = await groups(options.dedupe, root, entry, (id, importer) => this.resolve(id, importer, { skipSelf: true }));
|
|
719
|
+
},
|
|
720
|
+
// Modo dev: /vitral.json aponta para um módulo com o cliente HMR.
|
|
721
|
+
configureServer(server) {
|
|
722
|
+
const scope = options.scopeCss === false ? void 0 : scopeName();
|
|
723
|
+
serveDevManifest(server, () => devManifest(options.name ?? pkg.name ?? "remote", scope));
|
|
724
|
+
},
|
|
725
|
+
resolveId: {
|
|
726
|
+
order: "pre",
|
|
727
|
+
handler(id, importer) {
|
|
728
|
+
const own = dedupe && !serve ? hooks.resolveId.handler(id, importer) : null;
|
|
729
|
+
if (own) return own;
|
|
730
|
+
if (options.exposes && resolveExposesId(id)) return resolveExposesId(id);
|
|
731
|
+
if (id.endsWith(ENTRY_ID)) return VIRTUAL_ENTRY;
|
|
732
|
+
return resolveDevId(id);
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
load(id) {
|
|
736
|
+
const own = dedupe && !serve ? hooks.load(id) : null;
|
|
737
|
+
if (own != null) return own;
|
|
738
|
+
const exposed = options.exposes ? loadExposes(id, root, entry, options.exposes, options.adapter === false ? void 0 : ENTRY_ID) : null;
|
|
739
|
+
if (exposed != null) return exposed;
|
|
740
|
+
if (id === VIRTUAL_ENTRY) return entryCode(resolve4(root, entry), adapter, scopeName());
|
|
741
|
+
if (id === VIRTUAL_DEV_ENTRY) return devEntryCode(framework, options.adapter === false ? resolve4(root, entry) : void 0);
|
|
742
|
+
return loadPreamble(id);
|
|
743
|
+
},
|
|
744
|
+
transform(code, id) {
|
|
745
|
+
if (serve && options.scopeCss !== false) return scopeDevCss(code, id, scopeName());
|
|
746
|
+
},
|
|
66
747
|
writeBundle(_, bundle) {
|
|
748
|
+
if (isSplit(bundle)) return void (split = collect(outDir, bundle));
|
|
67
749
|
const files = Object.values(bundle);
|
|
68
|
-
const
|
|
69
|
-
if (!
|
|
750
|
+
const entry2 = files.find((f) => f.type === "chunk" && f.isEntry);
|
|
751
|
+
if (!entry2) return;
|
|
70
752
|
const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => {
|
|
71
|
-
const from =
|
|
72
|
-
let text =
|
|
73
|
-
|
|
74
|
-
const hash =
|
|
753
|
+
const from = join4(outDir, f.fileName);
|
|
754
|
+
let text = readFileSync3(from, "utf8");
|
|
755
|
+
text = transformCss(text, options, scopeName());
|
|
756
|
+
const hash = createHash2("sha256").update(text).digest("base64url").slice(0, 8);
|
|
75
757
|
const name = f.fileName.replace(/\.css$/, `-${hash}.css`);
|
|
76
|
-
|
|
77
|
-
if (name !== f.fileName)
|
|
758
|
+
writeFileSync2(join4(outDir, name), text);
|
|
759
|
+
if (name !== f.fileName) rmSync2(from);
|
|
78
760
|
return name;
|
|
79
761
|
});
|
|
80
|
-
const code =
|
|
81
|
-
|
|
762
|
+
const code = readFileSync3(join4(outDir, entry2.fileName));
|
|
763
|
+
manifest = {
|
|
82
764
|
name: options.name ?? pkg.name ?? "remote",
|
|
83
765
|
version: options.version ?? pkg.version,
|
|
84
|
-
entry:
|
|
766
|
+
entry: entry2.fileName,
|
|
85
767
|
css,
|
|
86
|
-
integrity: "sha384-" +
|
|
87
|
-
...options.scopeCss === false ? {} : { scope: scopeName() }
|
|
768
|
+
integrity: "sha384-" + createHash2("sha384").update(code).digest("base64"),
|
|
769
|
+
...options.scopeCss === false ? {} : { scope: scopeName() },
|
|
770
|
+
...options.exposes ? { exposes: Object.keys(exposeKeys(options.exposes)) } : {}
|
|
88
771
|
};
|
|
89
|
-
|
|
772
|
+
},
|
|
773
|
+
async closeBundle() {
|
|
774
|
+
if (!manifest) return;
|
|
775
|
+
const done = withSplit(manifest, outDir, split, shared);
|
|
776
|
+
manifest = split = void 0;
|
|
777
|
+
writeFileSync2(join4(outDir, "vitral.json"), JSON.stringify(done, null, 2) + "\n");
|
|
778
|
+
const props = options.types === false ? null : await extractProps(root, entryFile());
|
|
779
|
+
if (props) writeFileSync2(join4(outDir, "vitral.d.ts"), typesFile(done.name, props));
|
|
90
780
|
}
|
|
91
781
|
};
|
|
92
782
|
}
|