vitral 0.3.0 → 0.4.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/dist/angular.d.ts +2 -2
- package/dist/angular.js +7 -7
- package/dist/auto.js +7 -7
- package/dist/{capture-JYFERAPL.js → capture-TT5WBLJ6.js} +1 -1
- package/dist/channel-2YPYGX3J.js +95 -0
- package/dist/{chunk-AKNNHQ2H.js → chunk-463H6B56.js} +5 -0
- package/dist/chunk-54CBIZES.js +105 -0
- package/dist/{chunk-ZAC6QQI6.js → chunk-6EX5KYT5.js} +4 -4
- package/dist/{chunk-3YXI3G34.js → chunk-BCC25ANK.js} +11 -5
- package/dist/{chunk-TD4S3IHA.js → chunk-EMSB2NVX.js} +10 -8
- package/dist/{chunk-SDB5AZEI.js → chunk-IH3ZT3QU.js} +2 -2
- package/dist/{chunk-GNHCZRQP.js → chunk-TW7KYJQ6.js} +1 -1
- package/dist/{chunk-AH7KNMBW.js → chunk-UYOPJ4XQ.js} +1 -1
- package/dist/{chunk-IHTUM6LT.js → chunk-W6322KGP.js} +2 -2
- package/dist/{chunk-I3VSKSAZ.js → chunk-WD4CDGDZ.js} +21 -20
- package/dist/cli.js +1152 -37
- package/dist/devtools.d.ts +32 -2
- package/dist/devtools.js +27 -12
- package/dist/element.d.ts +12 -3
- package/dist/element.js +7 -7
- package/dist/embed.js +2 -0
- package/dist/{events-D5gs7rff.d.ts → events-Dkpkw_Sv.d.ts} +1 -1
- package/dist/expose-OVWTPHH5.js +15 -0
- package/dist/federation.d.ts +89 -0
- package/dist/federation.js +101 -0
- package/dist/iframe.js +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/overrides-NP754HY7.js +27 -0
- package/dist/preact.d.ts +4 -4
- package/dist/preact.js +6 -6
- package/dist/react.d.ts +3 -3
- package/dist/react.js +6 -6
- package/dist/routes.d.ts +2 -2
- package/dist/routes.js +5 -5
- package/dist/{shadow-6HELCHCJ.js → shadow-PVSETNMZ.js} +66 -5
- package/dist/single-spa.d.ts +40 -0
- package/dist/single-spa.js +52 -0
- package/dist/{slot-DqXTwGbs.d.ts → slot-UPg6ob9v.d.ts} +1 -1
- package/dist/solid.d.ts +3 -3
- package/dist/solid.js +6 -6
- package/dist/{sri-JMX6JLQP.js → sri-M7ZRU57G.js} +40 -10
- package/dist/svelte.d.ts +4 -4
- package/dist/svelte.js +6 -6
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +5 -5
- package/dist/{types-Czvm-siZ.d.ts → types-CA2p9KHC.d.ts} +112 -4
- package/dist/vite.d.ts +18 -0
- package/dist/vite.js +341 -35
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +6 -6
- package/package.json +79 -21
- package/dist/chunk-DXORSF4X.js +0 -42
- package/dist/expose-JUOUN5N5.js +0 -15
- package/dist/overrides-NZAIUGK5.js +0 -15
package/dist/vite.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/vite.ts
|
|
2
|
-
import { createHash as
|
|
3
|
-
import { readFileSync as
|
|
4
|
-
import { join as
|
|
2
|
+
import { createHash as createHash3 } from "crypto";
|
|
3
|
+
import { readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
4
|
+
import { join as join6, resolve as resolve5 } from "path";
|
|
5
5
|
|
|
6
6
|
// src/vite-exposes.ts
|
|
7
7
|
import { resolve } from "path";
|
|
@@ -105,9 +105,149 @@ function withSplit(m, outDir, s, groups2 = []) {
|
|
|
105
105
|
return { ...m, files, ...s && { split: { entry: s.entry, chunks: s.chunks } }, ...dedupe.length && { dedupe } };
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// src/vite/sbom.ts
|
|
109
|
+
import { createHash as createHash2 } from "crypto";
|
|
110
|
+
import { existsSync, readFileSync as readFileSync2, realpathSync } from "fs";
|
|
111
|
+
import { dirname, isAbsolute, join as join2, sep } from "path";
|
|
112
|
+
var SBOM_FILE = "sbom.cdx.json";
|
|
113
|
+
var readPkg = (dir) => {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(readFileSync2(join2(dir, "package.json"), "utf8"));
|
|
116
|
+
} catch {
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
function bundledFiles(bundle, into = /* @__PURE__ */ new Set()) {
|
|
121
|
+
for (const f of Object.values(bundle)) {
|
|
122
|
+
if (f.type !== "chunk" || !f.modules) continue;
|
|
123
|
+
for (const [id, m] of Object.entries(f.modules)) {
|
|
124
|
+
const file = id.split("?")[0];
|
|
125
|
+
if (m.renderedLength > 0 && isAbsolute(file)) into.add(file);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return into;
|
|
129
|
+
}
|
|
130
|
+
function packageDirs(files) {
|
|
131
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
132
|
+
const near = /* @__PURE__ */ new Map();
|
|
133
|
+
const nearest = (dir) => {
|
|
134
|
+
if (near.has(dir)) return near.get(dir);
|
|
135
|
+
const parent = dirname(dir);
|
|
136
|
+
const found = readPkg(dir)?.name ? dir : parent === dir ? null : nearest(parent);
|
|
137
|
+
near.set(dir, found);
|
|
138
|
+
return found;
|
|
139
|
+
};
|
|
140
|
+
const nm = `${sep}node_modules${sep}`;
|
|
141
|
+
for (const file of files) {
|
|
142
|
+
const at = file.lastIndexOf(nm);
|
|
143
|
+
if (at >= 0) {
|
|
144
|
+
const parts = file.slice(at + nm.length).split(sep);
|
|
145
|
+
const name = parts[0].startsWith("@") ? parts.slice(0, 2).join(sep) : parts[0];
|
|
146
|
+
if (parts.length > (parts[0].startsWith("@") ? 2 : 1)) dirs.add(file.slice(0, at + nm.length) + name);
|
|
147
|
+
} else {
|
|
148
|
+
const dir = nearest(dirname(file));
|
|
149
|
+
if (dir) dirs.add(dir);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return dirs;
|
|
153
|
+
}
|
|
154
|
+
function purl(name, version) {
|
|
155
|
+
const path = name.split("/").map(encodeURIComponent).join("/");
|
|
156
|
+
return `pkg:npm/${path}${version ? `@${encodeURIComponent(version)}` : ""}`;
|
|
157
|
+
}
|
|
158
|
+
function licenses(pkg) {
|
|
159
|
+
const raw = typeof pkg.license === "string" ? pkg.license : pkg.license?.type ?? pkg.licenses?.map((l) => l.type).filter(Boolean).join(" OR ");
|
|
160
|
+
if (!raw) return void 0;
|
|
161
|
+
const spdx = /^\(?[A-Za-z0-9.+-]+( (AND|OR|WITH) \(?[A-Za-z0-9.+-]+\)?)*\)?$/.test(raw) && raw !== "UNLICENSED";
|
|
162
|
+
return spdx ? [{ expression: raw }] : [{ license: { name: raw } }];
|
|
163
|
+
}
|
|
164
|
+
function component(pkg, type) {
|
|
165
|
+
const scoped = pkg.name.startsWith("@") && pkg.name.includes("/");
|
|
166
|
+
const ref = purl(pkg.name, pkg.version);
|
|
167
|
+
const license = licenses(pkg);
|
|
168
|
+
return {
|
|
169
|
+
type,
|
|
170
|
+
"bom-ref": ref,
|
|
171
|
+
...scoped && { group: pkg.name.slice(0, pkg.name.indexOf("/")) },
|
|
172
|
+
name: scoped ? pkg.name.slice(pkg.name.indexOf("/") + 1) : pkg.name,
|
|
173
|
+
...pkg.version && { version: pkg.version },
|
|
174
|
+
...pkg.description && { description: pkg.description },
|
|
175
|
+
...license && { licenses: license },
|
|
176
|
+
purl: ref
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function resolveDir(from, name) {
|
|
180
|
+
for (let dir = from; ; dir = dirname(dir)) {
|
|
181
|
+
const candidate = join2(dir, "node_modules", name);
|
|
182
|
+
if (existsSync(join2(candidate, "package.json"))) {
|
|
183
|
+
try {
|
|
184
|
+
return realpathSync(candidate);
|
|
185
|
+
} catch {
|
|
186
|
+
return candidate;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (dirname(dir) === dir) return void 0;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function createSbom(input) {
|
|
193
|
+
const rootDir = realpathSync(input.root);
|
|
194
|
+
const rootPkg = readPkg(rootDir) ?? {};
|
|
195
|
+
const main = component({ ...rootPkg, name: input.name, version: input.version }, "application");
|
|
196
|
+
const hashes = input.entry && [{ alg: "SHA-512", content: createHash2("sha512").update(input.entry).digest("hex") }];
|
|
197
|
+
const byDir = /* @__PURE__ */ new Map();
|
|
198
|
+
for (const dir of packageDirs(input.files)) {
|
|
199
|
+
let real = dir;
|
|
200
|
+
try {
|
|
201
|
+
real = realpathSync(dir);
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
const pkg = readPkg(real);
|
|
205
|
+
if (real === rootDir || !pkg?.name || byDir.has(real)) continue;
|
|
206
|
+
byDir.set(real, { pkg, ref: purl(pkg.name, pkg.version) });
|
|
207
|
+
}
|
|
208
|
+
const deps = (dir, pkg) => {
|
|
209
|
+
const names = Object.keys({ ...pkg.peerDependencies, ...pkg.optionalDependencies, ...pkg.dependencies });
|
|
210
|
+
const refs = /* @__PURE__ */ new Set();
|
|
211
|
+
for (const n of names) {
|
|
212
|
+
const hit = byDir.get(resolveDir(dir, n) ?? "");
|
|
213
|
+
if (hit) refs.add(hit.ref);
|
|
214
|
+
}
|
|
215
|
+
return [...refs].sort();
|
|
216
|
+
};
|
|
217
|
+
const components = /* @__PURE__ */ new Map();
|
|
218
|
+
const graph = /* @__PURE__ */ new Map([[main["bom-ref"], new Set(deps(rootDir, rootPkg))]]);
|
|
219
|
+
for (const [dir, { pkg, ref }] of byDir) {
|
|
220
|
+
if (!components.has(ref)) components.set(ref, component(pkg, "library"));
|
|
221
|
+
const set = graph.get(ref) ?? /* @__PURE__ */ new Set();
|
|
222
|
+
for (const d of deps(dir, pkg)) if (d !== ref) set.add(d);
|
|
223
|
+
graph.set(ref, set);
|
|
224
|
+
}
|
|
225
|
+
const epoch = Number(process.env.SOURCE_DATE_EPOCH);
|
|
226
|
+
const timestamp = input.timestamp ?? (Number.isFinite(epoch) && process.env.SOURCE_DATE_EPOCH ? new Date(epoch * 1e3) : /* @__PURE__ */ new Date());
|
|
227
|
+
const body = {
|
|
228
|
+
metadata: {
|
|
229
|
+
timestamp: timestamp.toISOString().replace(/\.\d{3}Z$/, "Z"),
|
|
230
|
+
tools: { components: [{ type: "application", name: "vitral", ...input.tool && { version: input.tool }, purl: purl("vitral", input.tool) }] },
|
|
231
|
+
component: { ...main, ...hashes && { hashes } }
|
|
232
|
+
},
|
|
233
|
+
components: [...components.values()].sort((a, b) => a["bom-ref"].localeCompare(b["bom-ref"])),
|
|
234
|
+
dependencies: [...graph].map(([ref, set]) => ({ ref, dependsOn: [...set].sort() }))
|
|
235
|
+
};
|
|
236
|
+
const h = createHash2("sha1").update(JSON.stringify(body)).digest("hex");
|
|
237
|
+
const serial = `urn:uuid:${h.slice(0, 8)}-${h.slice(8, 12)}-5${h.slice(13, 16)}-${(parseInt(h[16], 16) & 3 | 8).toString(16)}${h.slice(17, 20)}-${h.slice(20, 32)}`;
|
|
238
|
+
return {
|
|
239
|
+
$schema: "http://cyclonedx.org/schema/bom-1.6.schema.json",
|
|
240
|
+
bomFormat: "CycloneDX",
|
|
241
|
+
specVersion: "1.6",
|
|
242
|
+
serialNumber: serial,
|
|
243
|
+
version: 1,
|
|
244
|
+
...body
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
108
248
|
// src/vite/dedupe.ts
|
|
109
|
-
import { existsSync, readFileSync as
|
|
110
|
-
import { dirname, join as
|
|
249
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "fs";
|
|
250
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
111
251
|
import { pathToFileURL } from "url";
|
|
112
252
|
var REACT = ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "react/jsx-dev-runtime", "react/compiler-runtime"];
|
|
113
253
|
var BOOT = "virtual:vitral-boot";
|
|
@@ -118,10 +258,10 @@ var pkgOf = (spec) => spec.split("/").slice(0, spec.startsWith("@") ? 2 : 1).joi
|
|
|
118
258
|
var groupOf = (spec) => REACT.includes(spec) || pkgOf(spec) === "scheduler" ? "react" : pkgOf(spec);
|
|
119
259
|
var ident = /^[A-Za-z_$][\w$]*$/;
|
|
120
260
|
function versionOf(file, pkg) {
|
|
121
|
-
for (let dir =
|
|
122
|
-
const json =
|
|
123
|
-
if (!
|
|
124
|
-
const data = JSON.parse(
|
|
261
|
+
for (let dir = dirname2(file); dir !== dirname2(dir); dir = dirname2(dir)) {
|
|
262
|
+
const json = join3(dir, "package.json");
|
|
263
|
+
if (!existsSync2(json)) continue;
|
|
264
|
+
const data = JSON.parse(readFileSync3(json, "utf8"));
|
|
125
265
|
if (data.name === pkg) return data.version;
|
|
126
266
|
}
|
|
127
267
|
throw new Error(`vitral: vers\xE3o de ${pkg} n\xE3o encontrada`);
|
|
@@ -417,7 +557,7 @@ function splitShadowCss(text) {
|
|
|
417
557
|
}
|
|
418
558
|
|
|
419
559
|
// src/vite/adapter.ts
|
|
420
|
-
import { existsSync as
|
|
560
|
+
import { existsSync as existsSync3 } from "fs";
|
|
421
561
|
import { resolve as resolve3 } from "path";
|
|
422
562
|
var PLUGINS = [
|
|
423
563
|
[/^(preact:|prefresh$)/, "preact"],
|
|
@@ -456,10 +596,14 @@ import { component } from 'vitral'
|
|
|
456
596
|
function wrap(c) {
|
|
457
597
|
if (typeof c === 'function' && typeof HTMLElement !== 'undefined' && c.prototype instanceof HTMLElement) {
|
|
458
598
|
const base = ${JSON.stringify(`${scope}-remote`.toLowerCase().replace(/^[^a-z]+/, "x-"))}
|
|
459
|
-
|
|
460
|
-
//
|
|
461
|
-
|
|
462
|
-
|
|
599
|
+
// No registro do remote (ctx.customElements). Uma tag n\xE3o aceita outra
|
|
600
|
+
// classe: no HMR, a classe nova ganha tag nova.
|
|
601
|
+
return elementRemote(base, (r) => {
|
|
602
|
+
let tag = r.getName?.(c) || base
|
|
603
|
+
for (let n = 2; r.get(tag) && r.get(tag) !== c; n++) tag = base + '-' + n
|
|
604
|
+
r.get(tag) || r.define(tag, c)
|
|
605
|
+
return tag
|
|
606
|
+
})
|
|
463
607
|
}
|
|
464
608
|
if (typeof c === 'function') return component(c)
|
|
465
609
|
throw new Error('[vitral] o export default n\xE3o \xE9 um remote: exporte um componente, uma fun\xE7\xE3o ou um objeto com mount()')
|
|
@@ -471,21 +615,21 @@ var CANDIDATES = ["src/remote", "src/App", "src/app"];
|
|
|
471
615
|
var EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".vue", ".svelte"];
|
|
472
616
|
function findEntry(root) {
|
|
473
617
|
for (const base of CANDIDATES) {
|
|
474
|
-
for (const ext of EXTENSIONS) if (
|
|
618
|
+
for (const ext of EXTENSIONS) if (existsSync3(resolve3(root, base + ext))) return base + ext;
|
|
475
619
|
}
|
|
476
620
|
}
|
|
477
621
|
|
|
478
622
|
// src/vite/types.ts
|
|
479
623
|
import { createRequire as createRequire2 } from "module";
|
|
480
|
-
import { join as
|
|
624
|
+
import { join as join5 } from "path";
|
|
481
625
|
|
|
482
626
|
// src/vite/oxc.ts
|
|
483
|
-
import { existsSync as
|
|
627
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
484
628
|
import { createRequire } from "module";
|
|
485
|
-
import { dirname as
|
|
629
|
+
import { dirname as dirname3, join as join4, resolve as resolve4 } from "path";
|
|
486
630
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
487
631
|
async function loadOxc(root) {
|
|
488
|
-
const req = createRequire(
|
|
632
|
+
const req = createRequire(join4(root, "package.json"));
|
|
489
633
|
const ids = [() => req.resolve("oxc-transform"), () => createRequire(req.resolve("vite/package.json")).resolve("rolldown/experimental")];
|
|
490
634
|
for (const id of ids) {
|
|
491
635
|
try {
|
|
@@ -525,7 +669,7 @@ var Reader = class {
|
|
|
525
669
|
const cached = this.scopes.get(file);
|
|
526
670
|
if (cached) return cached;
|
|
527
671
|
const { ts } = this;
|
|
528
|
-
let code =
|
|
672
|
+
let code = readFileSync4(file, "utf8");
|
|
529
673
|
if (!/\.d\.[cm]?ts$/.test(file)) {
|
|
530
674
|
const out = this.oxc.isolatedDeclarationSync(file, code, {});
|
|
531
675
|
if (out.errors.length) unsupported();
|
|
@@ -738,10 +882,10 @@ var Reader = class {
|
|
|
738
882
|
}
|
|
739
883
|
};
|
|
740
884
|
function resolveFile(from, spec) {
|
|
741
|
-
const base = resolve4(
|
|
885
|
+
const base = resolve4(dirname3(from), spec);
|
|
742
886
|
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) =>
|
|
744
|
-
const file = candidates.find((f) => /\.[cm]?tsx?$/.test(f) &&
|
|
887
|
+
const candidates = [base, ...[".ts", ".tsx", ".mts", ".cts", ".d.ts"].map((ext) => stem + ext), ...["index.ts", "index.tsx", "index.d.ts"].map((f) => join4(base, f))];
|
|
888
|
+
const file = candidates.find((f) => /\.[cm]?tsx?$/.test(f) && existsSync4(f));
|
|
745
889
|
return file ?? unsupported();
|
|
746
890
|
}
|
|
747
891
|
|
|
@@ -754,7 +898,7 @@ export type Props = ${props}
|
|
|
754
898
|
async function loadTs(root) {
|
|
755
899
|
const api = (ts) => typeof ts?.createProgram === "function" ? ts : null;
|
|
756
900
|
try {
|
|
757
|
-
const ts = api(createRequire2(
|
|
901
|
+
const ts = api(createRequire2(join5(root, "package.json"))("typescript"));
|
|
758
902
|
if (ts) return ts;
|
|
759
903
|
} catch {
|
|
760
904
|
}
|
|
@@ -874,6 +1018,116 @@ var Printer = class {
|
|
|
874
1018
|
}
|
|
875
1019
|
};
|
|
876
1020
|
|
|
1021
|
+
// src/vite/mcp-app.ts
|
|
1022
|
+
var MCP_APP_PROTOCOL = "2026-01-26";
|
|
1023
|
+
var MCP_APP_GLOBAL = "__vitral_remote__";
|
|
1024
|
+
var MCP_RUNTIME = `function (w, mod, info) {
|
|
1025
|
+
var parent = w.parent, doc = w.document, seq = 0, pending = {}, handlers = {}, last = {}, context = {}
|
|
1026
|
+
var props = {}, mounted = null, ready = false, dirty = false
|
|
1027
|
+
function send(m) { m.jsonrpc = '2.0'; parent.postMessage(m, '*') }
|
|
1028
|
+
function request(method, params) {
|
|
1029
|
+
var id = ++seq
|
|
1030
|
+
return new Promise(function (ok, fail) {
|
|
1031
|
+
pending[id] = [ok, fail]
|
|
1032
|
+
send({ id: id, method: method, params: params || {} })
|
|
1033
|
+
})
|
|
1034
|
+
}
|
|
1035
|
+
function notify(method, params) { send({ method: method, params: params || {} }) }
|
|
1036
|
+
function report(e) { notify('notifications/message', { level: 'error', logger: info.name, data: String((e && e.message) || e) }) }
|
|
1037
|
+
function text(p, key) { return typeof p === 'string' ? p : p && p[key] }
|
|
1038
|
+
function push() { if (mounted && mounted.update) { try { mounted.update(Object.assign({}, props)) } catch (e) { report(e) } } }
|
|
1039
|
+
// Antes do mount terminar, s\xF3 guarda: o update sai uma vez, logo depois.
|
|
1040
|
+
function set(key, value) { props[key] = value; if (ready) push(); else dirty = true }
|
|
1041
|
+
function theme(c) {
|
|
1042
|
+
if (!c) return
|
|
1043
|
+
var root = doc.documentElement, vars = c.styles && c.styles.variables
|
|
1044
|
+
if (c.theme) { root.setAttribute('data-theme', c.theme); root.style.colorScheme = c.theme }
|
|
1045
|
+
for (var k in vars) if (vars[k] != null) root.style.setProperty(k, vars[k])
|
|
1046
|
+
}
|
|
1047
|
+
var events = {
|
|
1048
|
+
emit: function (type, payload) {
|
|
1049
|
+
last[type] = payload
|
|
1050
|
+
;(handlers[type] || []).slice().forEach(function (h) { try { h(payload) } catch (e) { w.console.error(e) } })
|
|
1051
|
+
if (type === 'mcp:message') request('ui/message', { role: 'user', content: [{ type: 'text', text: String(text(payload, 'text')) }] }).catch(report)
|
|
1052
|
+
else if (type === 'mcp:open-link') request('ui/open-link', { url: String(text(payload, 'url')) }).catch(report)
|
|
1053
|
+
else {
|
|
1054
|
+
context[type] = payload
|
|
1055
|
+
request('ui/update-model-context', { structuredContent: context, content: [{ type: 'text', text: JSON.stringify(context) }] }).catch(report)
|
|
1056
|
+
}
|
|
1057
|
+
},
|
|
1058
|
+
on: function (type, fn) {
|
|
1059
|
+
;(handlers[type] = handlers[type] || []).push(fn)
|
|
1060
|
+
return function () { handlers[type] = handlers[type].filter(function (h) { return h !== fn }) }
|
|
1061
|
+
},
|
|
1062
|
+
last: function (type) { return last[type] }
|
|
1063
|
+
}
|
|
1064
|
+
var root = doc.createElement('div')
|
|
1065
|
+
root.setAttribute('data-vitral-root', info.name)
|
|
1066
|
+
if (info.scope) root.setAttribute('data-vitral-scope', info.scope)
|
|
1067
|
+
var ctx = {
|
|
1068
|
+
name: info.name, baseUrl: w.location.href, events: events, shadowRoot: null, portalContainer: doc.body, protocol: 1,
|
|
1069
|
+
reportError: report,
|
|
1070
|
+
navigate: function (url) { request('ui/open-link', { url: String(url) }).catch(report) },
|
|
1071
|
+
mcp: { request: request, notify: notify, hostContext: function () { return props.hostContext } }
|
|
1072
|
+
}
|
|
1073
|
+
function size() {
|
|
1074
|
+
var h = doc.documentElement, old = h.style.height
|
|
1075
|
+
h.style.height = 'max-content'
|
|
1076
|
+
var height = Math.ceil(h.getBoundingClientRect().height)
|
|
1077
|
+
h.style.height = old
|
|
1078
|
+
notify('ui/notifications/size-changed', { width: Math.ceil(w.innerWidth), height: height })
|
|
1079
|
+
}
|
|
1080
|
+
var on = {
|
|
1081
|
+
'ui/notifications/tool-input': function (p) { set('toolInput', p.arguments) },
|
|
1082
|
+
'ui/notifications/tool-input-partial': function (p) { set('toolInputPartial', p.arguments) },
|
|
1083
|
+
'ui/notifications/tool-result': function (p) { set('toolResult', p) },
|
|
1084
|
+
'ui/notifications/tool-cancelled': function (p) { set('toolCancelled', p.reason || true) },
|
|
1085
|
+
'ui/notifications/host-context-changed': function (p) { theme(p); set('hostContext', Object.assign({}, props.hostContext, p)) },
|
|
1086
|
+
'ui/resource-teardown': function () { if (mounted) mounted.unmount(); mounted = null; return {} },
|
|
1087
|
+
ping: function () { return {} }
|
|
1088
|
+
}
|
|
1089
|
+
w.addEventListener('message', function (e) {
|
|
1090
|
+
var m = e.data
|
|
1091
|
+
if (e.source !== parent || !m || m.jsonrpc !== '2.0') return
|
|
1092
|
+
if (m.method === undefined) {
|
|
1093
|
+
var p = pending[m.id]
|
|
1094
|
+
if (!p) return
|
|
1095
|
+
delete pending[m.id]
|
|
1096
|
+
return m.error ? p[1](new Error(m.error.message)) : p[0](m.result)
|
|
1097
|
+
}
|
|
1098
|
+
var fn = on[m.method], result
|
|
1099
|
+
if (m.id === undefined) return void (fn && fn(m.params || {}))
|
|
1100
|
+
if (!fn) return send({ id: m.id, error: { code: -32601, message: 'm\xE9todo desconhecido: ' + m.method } })
|
|
1101
|
+
try { result = fn(m.params || {}) } catch (err) { return send({ id: m.id, error: { code: -32603, message: String(err && err.message || err) } }) }
|
|
1102
|
+
send({ id: m.id, result: result })
|
|
1103
|
+
})
|
|
1104
|
+
request('ui/initialize', {
|
|
1105
|
+
appInfo: { name: info.name, version: info.version || '0.0.0' }, appCapabilities: {}, protocolVersion: '${MCP_APP_PROTOCOL}'
|
|
1106
|
+
}).then(function (r) {
|
|
1107
|
+
props.hostContext = r && r.hostContext
|
|
1108
|
+
theme(props.hostContext)
|
|
1109
|
+
notify('ui/notifications/initialized')
|
|
1110
|
+
doc.body.appendChild(root)
|
|
1111
|
+
var remote = (mod && mod.default) || mod
|
|
1112
|
+
if (!remote || typeof remote.mount !== 'function') throw new Error('o m\xF3dulo n\xE3o exporta mount()')
|
|
1113
|
+
dirty = false
|
|
1114
|
+
return remote.mount(root, Object.assign({}, props), ctx)
|
|
1115
|
+
}).then(function (handle) {
|
|
1116
|
+
mounted = handle
|
|
1117
|
+
ready = true
|
|
1118
|
+
if (dirty) push()
|
|
1119
|
+
size()
|
|
1120
|
+
if (w.ResizeObserver) { var ro = new w.ResizeObserver(size); ro.observe(doc.documentElement); ro.observe(doc.body) }
|
|
1121
|
+
}).catch(report)
|
|
1122
|
+
}`;
|
|
1123
|
+
var inline = (text, tag) => text.replace(new RegExp(`</(${tag})`, "gi"), "<\\/$1").replace(/<!--/g, "<\\!--");
|
|
1124
|
+
function mcpAppHtml(page) {
|
|
1125
|
+
const info = JSON.stringify({ name: page.name, version: page.version, scope: page.scope });
|
|
1126
|
+
const styles = page.css.map((css) => `<style>${inline(css, "style")}</style>`).join("");
|
|
1127
|
+
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${page.name.replace(/[<&]/g, (c) => c === "<" ? "<" : "&")}</title><style>html,body{margin:0}body{display:flow-root}</style>${styles}</head><body><script>${inline(page.code, "script")}</script><script>(${MCP_RUNTIME})(window, ${MCP_APP_GLOBAL}, ${inline(info, "script")})</script></body></html>
|
|
1128
|
+
`;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
877
1131
|
// src/vite/dev.ts
|
|
878
1132
|
var DEV_ENTRY = "@vitral/entry.js";
|
|
879
1133
|
var VIRTUAL_DEV_ENTRY = "\0vitral:dev-entry";
|
|
@@ -971,6 +1225,7 @@ function vitral(options = {}) {
|
|
|
971
1225
|
let pkg = {};
|
|
972
1226
|
let manifest;
|
|
973
1227
|
let split;
|
|
1228
|
+
let modules = /* @__PURE__ */ new Set();
|
|
974
1229
|
let entry = options.entry;
|
|
975
1230
|
let adapter = "element";
|
|
976
1231
|
let framework = "element";
|
|
@@ -979,13 +1234,35 @@ function vitral(options = {}) {
|
|
|
979
1234
|
let shared = [];
|
|
980
1235
|
const dedupe = !!options.dedupe?.length;
|
|
981
1236
|
const hooks = dedupeHooks(() => options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entryFile() : ENTRY_ID, () => shared);
|
|
1237
|
+
const mcp = options.target === "mcp-app";
|
|
1238
|
+
if (mcp && (options.exposes || dedupe || options.shared?.length)) {
|
|
1239
|
+
throw new Error("[vitral] target: 'mcp-app' gera um HTML \xFAnico: n\xE3o combina com exposes, dedupe nem shared.");
|
|
1240
|
+
}
|
|
982
1241
|
const scopeName = () => (options.name ?? pkg.name ?? "remote").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
1242
|
+
const mcpApp = (files, js) => {
|
|
1243
|
+
const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => f.fileName);
|
|
1244
|
+
const read = (file) => {
|
|
1245
|
+
const text = readFileSync5(join6(outDir, file), "utf8");
|
|
1246
|
+
rmSync2(join6(outDir, file));
|
|
1247
|
+
return text;
|
|
1248
|
+
};
|
|
1249
|
+
const scope = options.scopeCss === false ? void 0 : scopeName();
|
|
1250
|
+
const html = mcpAppHtml({
|
|
1251
|
+
name: options.name ?? pkg.name ?? "remote",
|
|
1252
|
+
version: options.version ?? pkg.version,
|
|
1253
|
+
scope,
|
|
1254
|
+
code: read(js),
|
|
1255
|
+
css: css.map((f) => transformCss(read(f), options, scopeName()))
|
|
1256
|
+
});
|
|
1257
|
+
writeFileSync2(join6(outDir, "mcp-app.html"), html);
|
|
1258
|
+
};
|
|
983
1259
|
return {
|
|
984
1260
|
name: "vitral",
|
|
985
1261
|
config(user, { mode, command }) {
|
|
986
1262
|
entry ??= findEntry(resolve5(user.root ?? process.cwd()));
|
|
987
1263
|
if (!entry) throw new Error("[vitral] n\xE3o achei a entrada do remote (src/remote.* ou src/App.*). Use vitral({ entry }).");
|
|
988
1264
|
const rolldown = "rolldownVersion" in this.meta;
|
|
1265
|
+
const dir = options.versionDir ? versionDir(user.root ?? process.cwd(), user.build?.outDir, options.version) : void 0;
|
|
989
1266
|
return {
|
|
990
1267
|
// Código de biblioteca não tem process.env; React e Vue precisam disso.
|
|
991
1268
|
define: { "process.env.NODE_ENV": JSON.stringify(mode === "development" ? "development" : "production") },
|
|
@@ -995,12 +1272,18 @@ function vitral(options = {}) {
|
|
|
995
1272
|
// O remote não tem index.html: sem isso o Vite só descobre as
|
|
996
1273
|
// dependências no primeiro request e recarrega a página do host.
|
|
997
1274
|
optimizeDeps: user.optimizeDeps?.entries ? void 0 : { entries: [entry] },
|
|
998
|
-
build: {
|
|
1275
|
+
build: mcp ? {
|
|
1276
|
+
// Um IIFE só, sem chunks: o HTML do MCP App não pode buscar arquivos.
|
|
1277
|
+
lib: { entry: options.adapter === false ? entry : ENTRY_ID, formats: ["iife"], name: MCP_APP_GLOBAL, fileName: () => "mcp-app.js", cssFileName: "remote" },
|
|
1278
|
+
rollupOptions: { output: rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
|
|
1279
|
+
cssCodeSplit: false
|
|
1280
|
+
} : {
|
|
999
1281
|
// Nomes com hash: cache eterno no CDN. Só o vitral.json muda a cada deploy.
|
|
1000
1282
|
lib: { entry: dedupe ? BOOT : options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entry : ENTRY_ID, fileName: () => "remote-[hash].js", cssFileName: "remote" },
|
|
1001
1283
|
// Arquivo único (hosts antigos e caminho com blob:) e build dividido (manifesto v2).
|
|
1002
1284
|
rollupOptions: { external: options.shared ?? [], output: outputs(rolldown) },
|
|
1003
|
-
cssCodeSplit: false
|
|
1285
|
+
cssCodeSplit: false,
|
|
1286
|
+
...dir && { outDir: dir }
|
|
1004
1287
|
}
|
|
1005
1288
|
};
|
|
1006
1289
|
},
|
|
@@ -1011,7 +1294,7 @@ function vitral(options = {}) {
|
|
|
1011
1294
|
serve = c.command === "serve";
|
|
1012
1295
|
outDir = resolve5(c.root, c.build.outDir);
|
|
1013
1296
|
try {
|
|
1014
|
-
pkg = JSON.parse(
|
|
1297
|
+
pkg = JSON.parse(readFileSync5(join6(root, "package.json"), "utf8"));
|
|
1015
1298
|
} catch {
|
|
1016
1299
|
}
|
|
1017
1300
|
},
|
|
@@ -1056,20 +1339,22 @@ function vitral(options = {}) {
|
|
|
1056
1339
|
}
|
|
1057
1340
|
},
|
|
1058
1341
|
writeBundle(_, bundle) {
|
|
1342
|
+
if (options.sbom) bundledFiles(bundle, modules);
|
|
1059
1343
|
if (isSplit(bundle)) return void (split = collect(outDir, bundle));
|
|
1060
1344
|
const files = Object.values(bundle);
|
|
1061
1345
|
const entry2 = files.find((f) => f.type === "chunk" && f.isEntry);
|
|
1062
1346
|
if (!entry2) return;
|
|
1347
|
+
if (mcp) return mcpApp(files, entry2.fileName);
|
|
1063
1348
|
const emit = (file, text, kind = "") => {
|
|
1064
|
-
const hash =
|
|
1349
|
+
const hash = createHash3("sha256").update(text).digest("base64url").slice(0, 8);
|
|
1065
1350
|
const name = file.replace(/\.css$/, `${kind}-${hash}.css`);
|
|
1066
|
-
writeFileSync2(
|
|
1351
|
+
writeFileSync2(join6(outDir, name), text);
|
|
1067
1352
|
return name;
|
|
1068
1353
|
};
|
|
1069
1354
|
const shadow = { css: [] };
|
|
1070
1355
|
const css = files.filter((f) => f.type === "asset" && f.fileName.endsWith(".css")).map((f) => {
|
|
1071
|
-
const from =
|
|
1072
|
-
const text = transformCss(
|
|
1356
|
+
const from = join6(outDir, f.fileName);
|
|
1357
|
+
const text = transformCss(readFileSync5(from, "utf8"), options, scopeName());
|
|
1073
1358
|
const name = emit(f.fileName, text);
|
|
1074
1359
|
if (name !== f.fileName) rmSync2(from);
|
|
1075
1360
|
const split2 = splitShadowCss(text);
|
|
@@ -1079,14 +1364,14 @@ function vitral(options = {}) {
|
|
|
1079
1364
|
if (split2.rebase) shadow.rebase = true;
|
|
1080
1365
|
return name;
|
|
1081
1366
|
});
|
|
1082
|
-
const code =
|
|
1367
|
+
const code = readFileSync5(join6(outDir, entry2.fileName));
|
|
1083
1368
|
manifest = {
|
|
1084
1369
|
name: options.name ?? pkg.name ?? "remote",
|
|
1085
1370
|
version: options.version ?? pkg.version,
|
|
1086
1371
|
entry: entry2.fileName,
|
|
1087
1372
|
css,
|
|
1088
1373
|
...css.length ? { shadow } : {},
|
|
1089
|
-
integrity: "sha384-" +
|
|
1374
|
+
integrity: "sha384-" + createHash3("sha384").update(code).digest("base64"),
|
|
1090
1375
|
...options.scopeCss === false ? {} : { scope: scopeName() },
|
|
1091
1376
|
...options.exposes ? { exposes: Object.keys(exposeKeys(options.exposes)) } : {},
|
|
1092
1377
|
...contractOf(options.contract?.version, shared)
|
|
@@ -1095,13 +1380,34 @@ function vitral(options = {}) {
|
|
|
1095
1380
|
async closeBundle() {
|
|
1096
1381
|
if (!manifest) return;
|
|
1097
1382
|
const done = withSplit(manifest, outDir, split, shared);
|
|
1383
|
+
if (options.sbom) {
|
|
1384
|
+
const bom = createSbom({ root, name: done.name, version: done.version, files: modules, entry: readFileSync5(join6(outDir, done.entry)), tool: ownVersion() });
|
|
1385
|
+
writeFileSync2(join6(outDir, SBOM_FILE), JSON.stringify(bom, null, 2) + "\n");
|
|
1386
|
+
done.sbom = { file: SBOM_FILE, integrity: sri(join6(outDir, SBOM_FILE)) };
|
|
1387
|
+
}
|
|
1098
1388
|
manifest = split = void 0;
|
|
1099
|
-
|
|
1389
|
+
modules = /* @__PURE__ */ new Set();
|
|
1390
|
+
writeFileSync2(join6(outDir, "vitral.json"), JSON.stringify(done, null, 2) + "\n");
|
|
1100
1391
|
const props = options.types === false ? null : await extractProps(root, entryFile());
|
|
1101
|
-
if (props) writeFileSync2(
|
|
1392
|
+
if (props) writeFileSync2(join6(outDir, "vitral.d.ts"), typesFile(done.name, props));
|
|
1102
1393
|
}
|
|
1103
1394
|
};
|
|
1104
1395
|
}
|
|
1396
|
+
function ownVersion() {
|
|
1397
|
+
try {
|
|
1398
|
+
return JSON.parse(readFileSync5(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
1399
|
+
} catch {
|
|
1400
|
+
return void 0;
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
function versionDir(root, outDir = "dist", version) {
|
|
1404
|
+
try {
|
|
1405
|
+
version ??= JSON.parse(readFileSync5(join6(resolve5(root), "package.json"), "utf8")).version;
|
|
1406
|
+
} catch {
|
|
1407
|
+
}
|
|
1408
|
+
if (!version) throw new Error('[vitral] versionDir precisa de uma vers\xE3o: use vitral({ version }) ou "version" no package.json.');
|
|
1409
|
+
return join6(outDir, version);
|
|
1410
|
+
}
|
|
1105
1411
|
function contractOf(version, groups2) {
|
|
1106
1412
|
const contract = {
|
|
1107
1413
|
...version && { version },
|
package/dist/vue.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as vue from 'vue';
|
|
2
2
|
import { PropType, App, ShallowRef, WritableComputedRef, ComputedRef, Component } from 'vue';
|
|
3
|
-
import { P as Props, I as Isolation, R as RemoteContext, S as Shared, a as RemoteModule } from './types-
|
|
4
|
-
export { e as events } from './events-
|
|
3
|
+
import { P as Props, I as Isolation, R as RemoteContext, S as Shared, a as RemoteModule } from './types-CA2p9KHC.js';
|
|
4
|
+
export { e as events } from './events-Dkpkw_Sv.js';
|
|
5
5
|
import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
|
|
6
6
|
import './errors-kjBv6IH_.js';
|
|
7
7
|
|
|
@@ -127,8 +127,8 @@ declare const VitralRemote: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
127
127
|
onError?: ((...args: any[]) => any) | undefined;
|
|
128
128
|
onReady?: ((...args: any[]) => any) | undefined;
|
|
129
129
|
}>, {
|
|
130
|
-
isolate: Isolation;
|
|
131
130
|
name: string;
|
|
131
|
+
isolate: Isolation;
|
|
132
132
|
priority: RequestPriority;
|
|
133
133
|
loading: Loading;
|
|
134
134
|
src: string;
|
package/dist/vue.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hostSlot,
|
|
3
3
|
timings
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W6322KGP.js";
|
|
5
5
|
import {
|
|
6
6
|
defineRemote,
|
|
7
7
|
events,
|
|
8
8
|
memoSelect,
|
|
9
9
|
same,
|
|
10
10
|
shared
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-WD4CDGDZ.js";
|
|
12
|
+
import "./chunk-EMSB2NVX.js";
|
|
13
|
+
import "./chunk-6EX5KYT5.js";
|
|
14
14
|
import {
|
|
15
15
|
absolute
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
17
|
+
import "./chunk-463H6B56.js";
|
|
18
18
|
import "./chunk-GNPFWISJ.js";
|
|
19
19
|
|
|
20
20
|
// src/vue.ts
|