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/angular.js
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineVitralElement
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6Y3VMWHH.js";
|
|
4
|
+
import "./chunk-UTYAX6MU.js";
|
|
4
5
|
import {
|
|
5
|
-
configure,
|
|
6
6
|
defineRemote,
|
|
7
7
|
events,
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
memoSelect,
|
|
9
|
+
navigate,
|
|
10
|
+
same,
|
|
11
|
+
shared
|
|
12
|
+
} from "./chunk-NCONW6WS.js";
|
|
13
|
+
import {
|
|
14
|
+
configure
|
|
15
|
+
} from "./chunk-2XF5BKV3.js";
|
|
16
|
+
import "./chunk-SFL6LTP3.js";
|
|
17
|
+
import "./chunk-PX7PBCCT.js";
|
|
18
|
+
import "./chunk-GNPFWISJ.js";
|
|
10
19
|
|
|
11
20
|
// src/angular.ts
|
|
12
21
|
import {
|
|
22
|
+
DestroyRef,
|
|
13
23
|
InjectionToken,
|
|
14
24
|
createComponent,
|
|
15
25
|
inject,
|
|
16
26
|
provideAppInitializer,
|
|
17
27
|
provideZonelessChangeDetection,
|
|
18
|
-
reflectComponentType
|
|
28
|
+
reflectComponentType,
|
|
29
|
+
signal
|
|
19
30
|
} from "@angular/core";
|
|
20
31
|
import { createApplication } from "@angular/platform-browser";
|
|
21
32
|
var VITRAL_CONTEXT = new InjectionToken("vitral.context");
|
|
@@ -51,6 +62,14 @@ function angularRemote(component, config = {}) {
|
|
|
51
62
|
function injectVitral() {
|
|
52
63
|
return inject(VITRAL_CONTEXT, { optional: true });
|
|
53
64
|
}
|
|
65
|
+
function injectShared(key, select = same) {
|
|
66
|
+
const destroy = inject(DestroyRef);
|
|
67
|
+
const handle = shared(key);
|
|
68
|
+
const pick = memoSelect();
|
|
69
|
+
const value = signal(pick(handle.get(), select), { equal: Object.is });
|
|
70
|
+
destroy.onDestroy(handle.subscribe((v) => value.set(pick(v, select))));
|
|
71
|
+
return value.asReadonly();
|
|
72
|
+
}
|
|
54
73
|
function provideVitral(config = {}) {
|
|
55
74
|
return [
|
|
56
75
|
provideAppInitializer(() => {
|
|
@@ -64,6 +83,7 @@ export {
|
|
|
64
83
|
VITRAL_CONTEXT,
|
|
65
84
|
angularRemote,
|
|
66
85
|
events,
|
|
86
|
+
injectShared,
|
|
67
87
|
injectVitral,
|
|
68
88
|
navigate,
|
|
69
89
|
provideVitral
|
package/dist/auto.d.ts
ADDED
package/dist/auto.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineVitralElement
|
|
3
|
+
} from "./chunk-6Y3VMWHH.js";
|
|
4
|
+
import "./chunk-UTYAX6MU.js";
|
|
5
|
+
import "./chunk-NCONW6WS.js";
|
|
6
|
+
import "./chunk-2XF5BKV3.js";
|
|
7
|
+
import "./chunk-SFL6LTP3.js";
|
|
8
|
+
import "./chunk-PX7PBCCT.js";
|
|
9
|
+
import "./chunk-GNPFWISJ.js";
|
|
10
|
+
|
|
11
|
+
// src/auto.ts
|
|
12
|
+
defineVitralElement();
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
prefetchCss
|
|
3
|
+
} from "./chunk-SFL6LTP3.js";
|
|
4
|
+
import {
|
|
5
|
+
RemoteError,
|
|
6
|
+
absolute,
|
|
7
|
+
addLink,
|
|
8
|
+
fetchJson,
|
|
9
|
+
isRemoteError,
|
|
10
|
+
metric,
|
|
11
|
+
pageOrigin,
|
|
12
|
+
withRetry,
|
|
13
|
+
withTimeout
|
|
14
|
+
} from "./chunk-PX7PBCCT.js";
|
|
15
|
+
import {
|
|
16
|
+
protocol
|
|
17
|
+
} from "./chunk-GNPFWISJ.js";
|
|
18
|
+
|
|
19
|
+
// src/core/registry.ts
|
|
20
|
+
function configure(config) {
|
|
21
|
+
const p = protocol();
|
|
22
|
+
const { remotes, dedupe, ...rest } = config;
|
|
23
|
+
p.configure(rest);
|
|
24
|
+
if (dedupe) p.pending(import("./dedupe-IWFIXRWG.js").then((m) => m.offer(p, dedupe)).catch(() => {
|
|
25
|
+
}));
|
|
26
|
+
if (typeof remotes === "string") {
|
|
27
|
+
const url = absolute(remotes);
|
|
28
|
+
p.pending(
|
|
29
|
+
fetchJson(url, p.settings().timeout, "remotes", { cache: "no-cache" }).then((map) => registerAll(map, url))
|
|
30
|
+
).catch(() => {
|
|
31
|
+
});
|
|
32
|
+
} else if (remotes) {
|
|
33
|
+
registerAll(remotes);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function register(name, entry) {
|
|
37
|
+
const e = typeof entry === "string" ? { url: entry } : entry;
|
|
38
|
+
if (!e.url && !e.module) throw new RemoteError("NOT_REGISTERED", name, "informe url ou module");
|
|
39
|
+
if (!e.url) return protocol().register(name, e);
|
|
40
|
+
const url = absolute(e.url);
|
|
41
|
+
protocol().register(name, { ...e, url });
|
|
42
|
+
const { origin } = new URL(url);
|
|
43
|
+
if (typeof document !== "undefined" && origin !== pageOrigin() && origin !== "null" && !document.querySelector(`link[href="${origin}"]`)) {
|
|
44
|
+
addLink("preconnect", origin);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function registerSrc(src, name, trusted = true) {
|
|
48
|
+
const p = protocol();
|
|
49
|
+
const url = absolute(src);
|
|
50
|
+
const key = name || url;
|
|
51
|
+
if (p.entry(key)?.url !== url) p.register(key, { url });
|
|
52
|
+
const origin = new URL(url).origin;
|
|
53
|
+
const list = p.settings().trusted ?? [];
|
|
54
|
+
if (trusted && !list.includes(origin)) p.configure({ trusted: [...list, origin] });
|
|
55
|
+
return key;
|
|
56
|
+
}
|
|
57
|
+
function registerAll(map, base) {
|
|
58
|
+
for (const [name, entry] of Object.entries(map)) {
|
|
59
|
+
const e = typeof entry === "string" ? { url: entry } : entry;
|
|
60
|
+
register(name, e.url ? { ...e, url: absolute(e.url, base) } : e);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function checkOrigin(name, url) {
|
|
64
|
+
const p = protocol();
|
|
65
|
+
const origin = new URL(url).origin;
|
|
66
|
+
const { allowedOrigins, trusted = [] } = p.settings();
|
|
67
|
+
const allowed = [...allowedOrigins ?? [pageOrigin(), ...p.origins()].filter(Boolean), ...trusted];
|
|
68
|
+
if (allowed.includes("*") || allowed.includes(origin) || url.startsWith("blob:")) return;
|
|
69
|
+
throw new RemoteError("ORIGIN_BLOCKED", name, `origem ${origin} n\xE3o est\xE1 em allowedOrigins`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/core/loader.ts
|
|
73
|
+
function loadRemote(name) {
|
|
74
|
+
return load(name).then((r) => r.module);
|
|
75
|
+
}
|
|
76
|
+
function loadModule(name) {
|
|
77
|
+
return import("./expose-53BEJB34.js").then((m) => m.resolveModule(name, (n) => loadFile(n)));
|
|
78
|
+
}
|
|
79
|
+
function preload(name) {
|
|
80
|
+
load(name).catch(() => {
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
var paths;
|
|
84
|
+
function load(name, isolate, priority) {
|
|
85
|
+
const file = (n) => loadFile(n, isolate, priority);
|
|
86
|
+
if (protocol().entry(name) || !name.includes("/")) return file(name).then((r) => mountable(name, r));
|
|
87
|
+
return import("./expose-53BEJB34.js").then((m) => m.resolveTarget(name, file));
|
|
88
|
+
}
|
|
89
|
+
function loadFile(name, isolate, priority) {
|
|
90
|
+
const p = protocol();
|
|
91
|
+
return p.load(name, async () => {
|
|
92
|
+
paths ??= import("./sri-BVKZNX5Q.js").catch(() => null);
|
|
93
|
+
try {
|
|
94
|
+
await p.pending();
|
|
95
|
+
const override = await devOverride(name);
|
|
96
|
+
const entry = override ? { isolate: p.entry(name)?.isolate, ...override } : p.entry(name);
|
|
97
|
+
if (!entry) throw new RemoteError("NOT_REGISTERED", name, "remote n\xE3o registrado. Use configure({ remotes }).");
|
|
98
|
+
if (entry.module) return await loadLocal(name, entry);
|
|
99
|
+
let t = performance.now();
|
|
100
|
+
const resolved = await resolveEntry(name, entry, priority);
|
|
101
|
+
metric(name, "manifest", t);
|
|
102
|
+
prefetchCss(resolved.css, (isolate ?? resolved.isolate ?? p.settings().isolate) === "shadow", resolved.sri, priority);
|
|
103
|
+
t = performance.now();
|
|
104
|
+
const ns = await withRetry(p.settings().retries, () => importModule(name, resolved));
|
|
105
|
+
metric(name, "js", t);
|
|
106
|
+
return { ...resolved, module: ns?.default ?? ns, exports: ns };
|
|
107
|
+
} catch (e) {
|
|
108
|
+
throw isRemoteError(e) ? e : new RemoteError("LOAD_FAILED", name, String(e?.message ?? e), e);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function devOverride(name) {
|
|
113
|
+
try {
|
|
114
|
+
if (/vitral/.test(location.search + localStorage.getItem("vitral:overrides"))) return import("./overrides-NZAIUGK5.js").then((m) => m.overrideFor(name));
|
|
115
|
+
} catch {
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function loadLocal(name, entry) {
|
|
119
|
+
let ns = entry.module;
|
|
120
|
+
if (typeof ns === "function") ns = await ns();
|
|
121
|
+
return { module: ns?.default ?? ns, exports: ns, entry: typeof location !== "undefined" ? location.href : "http://localhost/", css: entry.css ?? [], isolate: entry.isolate };
|
|
122
|
+
}
|
|
123
|
+
async function resolveEntry(name, entry, priority) {
|
|
124
|
+
checkOrigin(name, entry.url);
|
|
125
|
+
const m = entry.manifest ?? (new URL(entry.url).pathname.endsWith(".json") ? await fetchJson(entry.url, protocol().settings().timeout, name, { cache: "no-cache", priority }) : { name, entry: entry.url });
|
|
126
|
+
if (typeof m?.entry !== "string") throw new RemoteError("INVALID_MODULE", name, `manifesto inv\xE1lido em ${entry.url}`);
|
|
127
|
+
const abs = (u) => absolute(u, entry.url);
|
|
128
|
+
const sri = {};
|
|
129
|
+
for (const file in m.files ?? {}) sri[abs(file)] = m.files[file];
|
|
130
|
+
const resolved = {
|
|
131
|
+
entry: abs(m.entry),
|
|
132
|
+
css: [...m.css ?? [], ...entry.css ?? []].map(abs),
|
|
133
|
+
// A integridade declarada pelo host vence a do manifesto, e aí só o
|
|
134
|
+
// arquivo único (o que ela descreve) é usado.
|
|
135
|
+
integrity: entry.integrity ?? m.integrity,
|
|
136
|
+
isolate: entry.isolate,
|
|
137
|
+
scope: m.scope,
|
|
138
|
+
sri,
|
|
139
|
+
priority,
|
|
140
|
+
split: m.split && !entry.integrity ? {
|
|
141
|
+
entry: abs(m.split.entry),
|
|
142
|
+
chunks: (m.split.chunks ?? []).map(abs),
|
|
143
|
+
sri,
|
|
144
|
+
priority,
|
|
145
|
+
dedupe: m.dedupe?.map((d) => ({ ...d, file: abs(d.file), chunks: d.chunks?.map(abs) }))
|
|
146
|
+
} : void 0
|
|
147
|
+
};
|
|
148
|
+
checkOrigin(name, resolved.entry);
|
|
149
|
+
for (const u of [resolved.split?.entry, ...(resolved.split?.dedupe ?? []).map((d) => d.file)]) if (u) checkOrigin(name, u);
|
|
150
|
+
if (name === entry.url && m.name) {
|
|
151
|
+
const override = await devOverride(m.name);
|
|
152
|
+
if (override) return { ...await resolveEntry(name, override), name: m.name };
|
|
153
|
+
resolved.name = m.name;
|
|
154
|
+
if (!protocol().entry(m.name)) protocol().register(m.name, entry);
|
|
155
|
+
}
|
|
156
|
+
return resolved;
|
|
157
|
+
}
|
|
158
|
+
async function importModule(name, r) {
|
|
159
|
+
const { timeout } = protocol().settings();
|
|
160
|
+
const run = (url) => withTimeout(timeout, name, import(
|
|
161
|
+
/* @vite-ignore */
|
|
162
|
+
/* webpackIgnore: true */
|
|
163
|
+
url
|
|
164
|
+
)).catch((e) => {
|
|
165
|
+
throw isRemoteError(e) ? e : new RemoteError("LOAD_FAILED", name, `falha ao importar ${r.entry}`, e);
|
|
166
|
+
});
|
|
167
|
+
if (!r.integrity) return run(r.entry);
|
|
168
|
+
const sri = await paths;
|
|
169
|
+
if (!sri) throw new RemoteError("LOAD_FAILED", name, "n\xE3o foi poss\xEDvel carregar o verificador de integrity");
|
|
170
|
+
return sri.importVerified(name, r, run, timeout);
|
|
171
|
+
}
|
|
172
|
+
function mountable(name, r) {
|
|
173
|
+
if (typeof r.module?.mount != "function") {
|
|
174
|
+
throw new RemoteError("INVALID_MODULE", name, "o m\xF3dulo n\xE3o exporta mount(). Use defineRemote(), ou loadModule() para m\xF3dulo sem UI.");
|
|
175
|
+
}
|
|
176
|
+
return r;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export {
|
|
180
|
+
configure,
|
|
181
|
+
register,
|
|
182
|
+
registerSrc,
|
|
183
|
+
loadRemote,
|
|
184
|
+
loadModule,
|
|
185
|
+
preload,
|
|
186
|
+
load,
|
|
187
|
+
loadFile,
|
|
188
|
+
resolveEntry,
|
|
189
|
+
mountable
|
|
190
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hostSlot,
|
|
3
|
+
timings
|
|
4
|
+
} from "./chunk-UTYAX6MU.js";
|
|
5
|
+
import {
|
|
6
|
+
defineRemote,
|
|
7
|
+
memoSelect,
|
|
8
|
+
same,
|
|
9
|
+
shared
|
|
10
|
+
} from "./chunk-NCONW6WS.js";
|
|
11
|
+
import {
|
|
12
|
+
registerSrc
|
|
13
|
+
} from "./chunk-2XF5BKV3.js";
|
|
14
|
+
|
|
15
|
+
// src/element.ts
|
|
16
|
+
var Base = typeof HTMLElement === "undefined" ? class {
|
|
17
|
+
} : HTMLElement;
|
|
18
|
+
var VitralRemoteElement = class extends Base {
|
|
19
|
+
static {
|
|
20
|
+
this.observedAttributes = ["name", "src", "props", "isolate"];
|
|
21
|
+
}
|
|
22
|
+
#slot = null;
|
|
23
|
+
#props = {};
|
|
24
|
+
get props() {
|
|
25
|
+
return this.#props;
|
|
26
|
+
}
|
|
27
|
+
set props(value) {
|
|
28
|
+
this.#props = value ?? {};
|
|
29
|
+
this.#slot?.update(this.#props);
|
|
30
|
+
}
|
|
31
|
+
get status() {
|
|
32
|
+
return this.#slot?.status ?? "loading";
|
|
33
|
+
}
|
|
34
|
+
retry() {
|
|
35
|
+
this.#slot?.retry();
|
|
36
|
+
}
|
|
37
|
+
connectedCallback() {
|
|
38
|
+
if (this.#slot) return;
|
|
39
|
+
const name = this.#name();
|
|
40
|
+
if (!name) return;
|
|
41
|
+
if (this.hasAttribute("props") && !Object.keys(this.#props).length) this.#props = parseProps(this.getAttribute("props"));
|
|
42
|
+
const keep = this.getAttribute("keep-alive");
|
|
43
|
+
this.#slot = hostSlot(this, {
|
|
44
|
+
name,
|
|
45
|
+
props: this.#props,
|
|
46
|
+
isolate: this.getAttribute("isolate") || void 0,
|
|
47
|
+
loading: this.getAttribute("loading"),
|
|
48
|
+
prefetch: this.getAttribute("prefetch"),
|
|
49
|
+
priority: this.getAttribute("priority") || void 0,
|
|
50
|
+
keepAlive: keep === null ? false : Number(keep) || true,
|
|
51
|
+
styles: { inherit: this.getAttribute("inherit-styles")?.split(/\s+/).filter(Boolean) },
|
|
52
|
+
onStatus: (status, error) => {
|
|
53
|
+
this.setAttribute("data-vitral-status", status);
|
|
54
|
+
if (status === "loading") this.setAttribute("aria-busy", "true");
|
|
55
|
+
else this.removeAttribute("aria-busy");
|
|
56
|
+
const has = (slot) => {
|
|
57
|
+
const els = this.querySelectorAll(`:scope > [slot="${slot}"]`);
|
|
58
|
+
for (const el of els) el.hidden = status !== (slot === "fallback" ? "loading" : "error");
|
|
59
|
+
return els.length > 0;
|
|
60
|
+
};
|
|
61
|
+
queueMicrotask(() => {
|
|
62
|
+
if (this.#slot?.status !== status) return;
|
|
63
|
+
const custom = { loading: has("fallback"), error: has("error"), ready: true };
|
|
64
|
+
this.#showDefault(custom[status] ? null : status);
|
|
65
|
+
});
|
|
66
|
+
if (status === "ready") this.dispatchEvent(new CustomEvent("vitral-ready", { bubbles: true, detail: { timings: timings(name) } }));
|
|
67
|
+
if (status === "error") this.dispatchEvent(new CustomEvent("vitral-error", { bubbles: true, detail: { error } }));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Nome para montar. `src` em atributo é registrado sem entrar na allowlist:
|
|
73
|
+
* HTML injetado não pode liberar uma origem nova quando há `allowedOrigins`.
|
|
74
|
+
*/
|
|
75
|
+
#name() {
|
|
76
|
+
const src = this.getAttribute("src");
|
|
77
|
+
const name = this.getAttribute("name");
|
|
78
|
+
return src ? registerSrc(src, name ?? void 0, false) : name;
|
|
79
|
+
}
|
|
80
|
+
#default = null;
|
|
81
|
+
/** Carregando e erro padrão, só quando não há slot próprio. */
|
|
82
|
+
#showDefault(status) {
|
|
83
|
+
this.#default?.remove();
|
|
84
|
+
this.#default = null;
|
|
85
|
+
if (!status) return;
|
|
86
|
+
const box = document.createElement("div");
|
|
87
|
+
box.setAttribute("data-vitral-default", status);
|
|
88
|
+
if (status === "loading") {
|
|
89
|
+
box.setAttribute("role", "status");
|
|
90
|
+
box.textContent = "Carregando\u2026";
|
|
91
|
+
} else {
|
|
92
|
+
box.setAttribute("role", "alert");
|
|
93
|
+
const button = document.createElement("button");
|
|
94
|
+
button.type = "button";
|
|
95
|
+
button.textContent = "Tentar de novo";
|
|
96
|
+
button.onclick = () => this.retry();
|
|
97
|
+
box.append("N\xE3o foi poss\xEDvel carregar. ", button);
|
|
98
|
+
}
|
|
99
|
+
this.prepend(this.#default = box);
|
|
100
|
+
}
|
|
101
|
+
disconnectedCallback() {
|
|
102
|
+
queueMicrotask(() => {
|
|
103
|
+
if (!this.isConnected) {
|
|
104
|
+
this.#slot?.destroy();
|
|
105
|
+
this.#slot = null;
|
|
106
|
+
this.#showDefault(null);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
attributeChangedCallback(attr, _old, value) {
|
|
111
|
+
if (attr === "props") return void (this.props = parseProps(value));
|
|
112
|
+
if (!this.#slot) return void (this.isConnected && this.connectedCallback());
|
|
113
|
+
if (attr === "name" || attr === "src") {
|
|
114
|
+
const name = this.#name();
|
|
115
|
+
if (name) this.#slot.set({ name });
|
|
116
|
+
}
|
|
117
|
+
if (attr === "isolate") this.#slot.set({ isolate: value || void 0 });
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
function parseProps(value) {
|
|
121
|
+
if (!value) return {};
|
|
122
|
+
try {
|
|
123
|
+
return JSON.parse(value);
|
|
124
|
+
} catch {
|
|
125
|
+
console.error("[vitral] atributo props n\xE3o \xE9 JSON v\xE1lido:", value);
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function defineVitralElement(tag = "vitral-remote") {
|
|
130
|
+
if (typeof customElements !== "undefined" && !customElements.get(tag)) {
|
|
131
|
+
customElements.define(tag, class extends VitralRemoteElement {
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function elementRemote(tag, setup) {
|
|
136
|
+
return defineRemote({
|
|
137
|
+
mount(el, props, ctx) {
|
|
138
|
+
setup?.();
|
|
139
|
+
const node = document.createElement(tag);
|
|
140
|
+
node.vitral = ctx;
|
|
141
|
+
Object.assign(node, props);
|
|
142
|
+
el.appendChild(node);
|
|
143
|
+
return {
|
|
144
|
+
update: (next) => Object.assign(node, next),
|
|
145
|
+
unmount: () => node.remove()
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
var SharedController = class {
|
|
151
|
+
#host;
|
|
152
|
+
#handle;
|
|
153
|
+
#select;
|
|
154
|
+
#pick = memoSelect();
|
|
155
|
+
#off;
|
|
156
|
+
constructor(host, key, select) {
|
|
157
|
+
this.#host = host;
|
|
158
|
+
this.#handle = shared(key);
|
|
159
|
+
this.#select = select ?? same;
|
|
160
|
+
this.value = this.#pick(this.#handle.get(), this.#select);
|
|
161
|
+
host.addController(this);
|
|
162
|
+
}
|
|
163
|
+
hostConnected() {
|
|
164
|
+
this.#off = this.#handle.subscribe((v) => {
|
|
165
|
+
const next = this.#pick(v, this.#select);
|
|
166
|
+
if (Object.is(next, this.value)) return;
|
|
167
|
+
this.value = next;
|
|
168
|
+
this.#host.requestUpdate();
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
hostDisconnected() {
|
|
172
|
+
this.#off?.();
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export {
|
|
177
|
+
VitralRemoteElement,
|
|
178
|
+
defineVitralElement,
|
|
179
|
+
elementRemote,
|
|
180
|
+
SharedController
|
|
181
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
protocol
|
|
3
|
+
} from "./chunk-GNPFWISJ.js";
|
|
4
|
+
|
|
5
|
+
// src/core/overrides.ts
|
|
6
|
+
var OVERRIDES_KEY = "vitral:overrides";
|
|
7
|
+
function overridesEnabled() {
|
|
8
|
+
return !!protocol().settings().devOverrides || typeof location !== "undefined" && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(location.hostname);
|
|
9
|
+
}
|
|
10
|
+
var manifestUrl = (url) => /\.(json|m?js)(\?|$)/.test(url) ? url : url.replace(/\/?$/, "/vitral.json");
|
|
11
|
+
function storedOverrides() {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(localStorage.getItem(OVERRIDES_KEY) ?? "{}") ?? {};
|
|
14
|
+
} catch {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
var warned = /* @__PURE__ */ new Set();
|
|
19
|
+
function overrideFor(name) {
|
|
20
|
+
if (!overridesEnabled()) return;
|
|
21
|
+
const all = storedOverrides();
|
|
22
|
+
for (const pair of new URLSearchParams(location.search).getAll("vitral").join(",").split(",")) {
|
|
23
|
+
const at = pair.indexOf("@");
|
|
24
|
+
if (at > 0) all[pair.slice(0, at)] = pair.slice(at + 1);
|
|
25
|
+
}
|
|
26
|
+
if (!all[name]) return;
|
|
27
|
+
const url = new URL(manifestUrl(all[name]), location.href).href;
|
|
28
|
+
const p = protocol();
|
|
29
|
+
const trusted = p.settings().trusted ?? [];
|
|
30
|
+
const origin = new URL(url).origin;
|
|
31
|
+
if (!trusted.includes(origin)) p.configure({ trusted: [...trusted, origin] });
|
|
32
|
+
if (!warned.has(name)) console.warn(`[vitral] override ativo: ${name} \u2192 ${url}`), warned.add(name);
|
|
33
|
+
return { url };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
OVERRIDES_KEY,
|
|
38
|
+
overridesEnabled,
|
|
39
|
+
manifestUrl,
|
|
40
|
+
storedOverrides,
|
|
41
|
+
overrideFor
|
|
42
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// src/core/bus.ts
|
|
2
|
+
function createEventBus() {
|
|
3
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
4
|
+
const lastValues = /* @__PURE__ */ new Map();
|
|
5
|
+
return {
|
|
6
|
+
emit(type, payload) {
|
|
7
|
+
lastValues.set(type, payload);
|
|
8
|
+
for (const h of [...handlers.get(type) ?? []]) {
|
|
9
|
+
try {
|
|
10
|
+
h(payload);
|
|
11
|
+
} catch (e) {
|
|
12
|
+
console.error(`[vitral] handler de "${type}" falhou`, e);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
on(type, handler) {
|
|
17
|
+
let set = handlers.get(type);
|
|
18
|
+
if (!set) handlers.set(type, set = /* @__PURE__ */ new Set());
|
|
19
|
+
set.add(handler);
|
|
20
|
+
return () => set.delete(handler);
|
|
21
|
+
},
|
|
22
|
+
last(type) {
|
|
23
|
+
return lastValues.get(type);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/core/state.ts
|
|
29
|
+
var PROTOCOL = 1;
|
|
30
|
+
var KEY = /* @__PURE__ */ Symbol.for("vitral");
|
|
31
|
+
var g = globalThis;
|
|
32
|
+
function createProtocol() {
|
|
33
|
+
const settings = { timeout: 15e3, retries: 1, isolate: "none", allowedOrigins: null };
|
|
34
|
+
const entries = /* @__PURE__ */ new Map();
|
|
35
|
+
const modules = /* @__PURE__ */ new Map();
|
|
36
|
+
let ready = Promise.resolve();
|
|
37
|
+
return {
|
|
38
|
+
protocol: PROTOCOL,
|
|
39
|
+
events: createEventBus(),
|
|
40
|
+
settings: () => settings,
|
|
41
|
+
configure(patch) {
|
|
42
|
+
Object.assign(settings, patch);
|
|
43
|
+
},
|
|
44
|
+
register(name, entry) {
|
|
45
|
+
entries.set(name, entry);
|
|
46
|
+
modules.delete(name);
|
|
47
|
+
},
|
|
48
|
+
entry: (name) => entries.get(name),
|
|
49
|
+
origins: () => [...entries.values()].filter((e) => e.url).map((e) => new URL(e.url).origin),
|
|
50
|
+
pending(p) {
|
|
51
|
+
if (p) ready = Promise.all([ready, p]);
|
|
52
|
+
return ready.then(() => {
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
load(name, fetcher) {
|
|
56
|
+
let p = modules.get(name);
|
|
57
|
+
if (!p) {
|
|
58
|
+
p = fetcher();
|
|
59
|
+
const mine = p;
|
|
60
|
+
mine.catch(() => modules.get(name) === mine && modules.delete(name));
|
|
61
|
+
modules.set(name, p);
|
|
62
|
+
}
|
|
63
|
+
return p;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function protocol() {
|
|
68
|
+
const found = g[KEY];
|
|
69
|
+
if (found && typeof found.protocol === "number" && found.protocol >= PROTOCOL) return found;
|
|
70
|
+
return g[KEY] = createProtocol();
|
|
71
|
+
}
|
|
72
|
+
function resetProtocol() {
|
|
73
|
+
delete g[KEY];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
createEventBus,
|
|
78
|
+
protocol,
|
|
79
|
+
resetProtocol
|
|
80
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mountable
|
|
3
|
+
} from "./chunk-2XF5BKV3.js";
|
|
4
|
+
import {
|
|
5
|
+
RemoteError
|
|
6
|
+
} from "./chunk-PX7PBCCT.js";
|
|
7
|
+
import {
|
|
8
|
+
protocol
|
|
9
|
+
} from "./chunk-GNPFWISJ.js";
|
|
10
|
+
|
|
11
|
+
// src/core/expose.ts
|
|
12
|
+
function splitName(name) {
|
|
13
|
+
const p = protocol();
|
|
14
|
+
let i = name.length;
|
|
15
|
+
if (!p.entry(name)) while ((i = name.lastIndexOf("/", i - 1)) > 0 && !p.entry(name.slice(0, i))) ;
|
|
16
|
+
return i > 0 && i < name.length ? [name.slice(0, i), "." + name.slice(i)] : [name, null];
|
|
17
|
+
}
|
|
18
|
+
function resolveTarget(name, loadFile) {
|
|
19
|
+
return resolveAny(name, loadFile).then((r) => mountable(name, r));
|
|
20
|
+
}
|
|
21
|
+
function resolveAny(name, loadFile) {
|
|
22
|
+
const p = protocol();
|
|
23
|
+
if (p.entry(name) || !name.includes("/")) return loadFile(name);
|
|
24
|
+
return p.pending().then(async () => {
|
|
25
|
+
const [remote, key] = splitName(name);
|
|
26
|
+
if (!key) return loadFile(name);
|
|
27
|
+
const r = await loadFile(remote);
|
|
28
|
+
const table = r.exports?.exposes;
|
|
29
|
+
if (!table?.[key]) throw new RemoteError("NOT_EXPOSED", name, `${remote} n\xE3o exp\xF5e ${key}. Expostos: ${Object.keys(table ?? {}).join(", ")}`);
|
|
30
|
+
try {
|
|
31
|
+
const value = table[key];
|
|
32
|
+
const ns = await (typeof value == "function" ? value() : value);
|
|
33
|
+
return { ...r, module: ns?.default ?? ns, exports: ns };
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new RemoteError("LOAD_FAILED", name, String(e), e);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function resolveModule(name, loadFile) {
|
|
40
|
+
const r = await resolveAny(name, loadFile);
|
|
41
|
+
if (!r.exports) {
|
|
42
|
+
throw new RemoteError("INVALID_MODULE", name, "o remote foi carregado por uma c\xF3pia antiga da lib, que n\xE3o guarda os exports");
|
|
43
|
+
}
|
|
44
|
+
return r.exports;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
splitName,
|
|
49
|
+
resolveTarget,
|
|
50
|
+
resolveModule
|
|
51
|
+
};
|