vitral 0.4.0 → 0.6.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 +5 -5
- package/dist/auto.js +5 -5
- package/dist/chunk-B2MPYF4M.js +27 -0
- package/dist/chunk-DAESKNQ6.js +207 -0
- package/dist/{chunk-WD4CDGDZ.js → chunk-HIVMSPGM.js} +12 -11
- package/dist/{chunk-IH3ZT3QU.js → chunk-JBNITHPI.js} +1 -1
- package/dist/{chunk-6EX5KYT5.js → chunk-KU6HF2EW.js} +2 -2
- package/dist/chunk-NZEQGRBL.js +93 -0
- package/dist/chunk-OVVGVPIV.js +21 -0
- package/dist/{chunk-BCC25ANK.js → chunk-PLM7U7LR.js} +10 -6
- package/dist/chunk-PY7P5BF4.js +404 -0
- package/dist/{chunk-EMSB2NVX.js → chunk-S7PIVPBX.js} +10 -4
- package/dist/{chunk-W6322KGP.js → chunk-UXLKRSOM.js} +2 -2
- package/dist/cli.js +414 -44
- package/dist/dict.d.ts +69 -0
- package/dist/dict.js +8 -0
- package/dist/edge.d.ts +124 -0
- package/dist/edge.js +413 -0
- package/dist/element.d.ts +2 -2
- package/dist/element.js +5 -5
- package/dist/embed.js +2 -2
- package/dist/{events-Dkpkw_Sv.d.ts → events-0rxFlWJJ.d.ts} +1 -1
- package/dist/{expose-OVWTPHH5.js → expose-EQOWTJNC.js} +3 -3
- package/dist/federation.d.ts +1 -1
- package/dist/hydrate-R76V2I36.js +182 -0
- package/dist/iframe.js +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/match-CMBM_jLW.d.ts +16 -0
- package/dist/otel.d.ts +29 -1
- package/dist/otel.js +13 -1
- package/dist/preact.d.ts +4 -4
- package/dist/preact.js +4 -4
- package/dist/prefetch.d.ts +25 -0
- package/dist/prefetch.js +178 -0
- package/dist/react-server.d.ts +20 -0
- package/dist/react-server.js +13 -0
- package/dist/react.d.ts +7 -4
- package/dist/react.js +19 -31
- package/dist/reframe-MUV472OU.js +251 -0
- package/dist/routes.d.ts +4 -13
- package/dist/routes.js +27 -23
- package/dist/{shadow-PVSETNMZ.js → shadow-S4SKHTA7.js} +2 -2
- package/dist/single-spa.d.ts +1 -1
- package/dist/{slot-UPg6ob9v.d.ts → slot-D49L1rdU.d.ts} +1 -1
- package/dist/solid.d.ts +3 -3
- package/dist/solid.js +4 -4
- package/dist/{sri-M7ZRU57G.js → sri-576GTDIA.js} +2 -1
- package/dist/svelte.d.ts +4 -4
- package/dist/svelte.js +4 -4
- package/dist/testing.d.ts +171 -3
- package/dist/testing.js +191 -4
- package/dist/{types-CA2p9KHC.d.ts → types-DUtcF3HO.d.ts} +12 -1
- package/dist/vitals.d.ts +29 -0
- package/dist/vitals.js +152 -0
- package/dist/vite.js +28 -422
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +4 -4
- package/package.json +111 -16
package/dist/prefetch.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveEntry
|
|
3
|
+
} from "./chunk-S7PIVPBX.js";
|
|
4
|
+
import "./chunk-KU6HF2EW.js";
|
|
5
|
+
import {
|
|
6
|
+
addLink
|
|
7
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
8
|
+
import "./chunk-463H6B56.js";
|
|
9
|
+
import {
|
|
10
|
+
protocol
|
|
11
|
+
} from "./chunk-GNPFWISJ.js";
|
|
12
|
+
|
|
13
|
+
// src/core/markov.ts
|
|
14
|
+
var LIMITS = { routes: 50, next: 10, remotes: 8, total: 1e3, key: 200 };
|
|
15
|
+
var ok = (k) => typeof k === "string" && k.length <= LIMITS.key && k !== "__proto__";
|
|
16
|
+
var sum = (row) => Object.values(row).reduce((a, b) => a + b, 0);
|
|
17
|
+
var smallest = (o, keep) => Object.keys(o).filter((k) => k !== keep).reduce((min, k) => min === void 0 || o[k] < o[min] ? k : min, void 0);
|
|
18
|
+
var empty = () => ({ t: {}, r: {} });
|
|
19
|
+
function parse(text) {
|
|
20
|
+
try {
|
|
21
|
+
const c = JSON.parse(text ?? "");
|
|
22
|
+
const rows = Object.values(c.t).every((row) => row && typeof row === "object" && Object.values(row).every((n) => Number.isFinite(n)));
|
|
23
|
+
const lists = Object.values(c.r).every((l) => Array.isArray(l) && l.every((n) => typeof n === "string"));
|
|
24
|
+
if (rows && lists) return c;
|
|
25
|
+
} catch {
|
|
26
|
+
}
|
|
27
|
+
return empty();
|
|
28
|
+
}
|
|
29
|
+
function record(c, from, to) {
|
|
30
|
+
if (from === to || !ok(from) || !ok(to)) return;
|
|
31
|
+
const row = c.t[from] ??= {};
|
|
32
|
+
row[to] = (row[to] ?? 0) + 1;
|
|
33
|
+
if (sum(row) > LIMITS.total) {
|
|
34
|
+
for (const k in row) if (!(row[k] >>= 1)) delete row[k];
|
|
35
|
+
}
|
|
36
|
+
if (Object.keys(row).length > LIMITS.next) delete row[smallest(row, to)];
|
|
37
|
+
if (Object.keys(c.t).length > LIMITS.routes) {
|
|
38
|
+
const totals = Object.fromEntries(Object.entries(c.t).map(([k, v]) => [k, sum(v)]));
|
|
39
|
+
delete c.t[smallest(totals, from)];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function remember(c, route, remote) {
|
|
43
|
+
if (!ok(route)) return false;
|
|
44
|
+
const list = c.r[route] ??= [];
|
|
45
|
+
if (list.includes(remote)) return false;
|
|
46
|
+
list.push(remote);
|
|
47
|
+
if (list.length > LIMITS.remotes) list.shift();
|
|
48
|
+
const routes = Object.keys(c.r);
|
|
49
|
+
if (routes.length > LIMITS.routes) delete c.r[routes.find((k) => k !== route)];
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
function predict(c, from, threshold, min = 1) {
|
|
53
|
+
const row = Object.prototype.hasOwnProperty.call(c.t, from) ? c.t[from] : void 0;
|
|
54
|
+
if (!row) return null;
|
|
55
|
+
const total = sum(row);
|
|
56
|
+
let best = null;
|
|
57
|
+
for (const k in row) if (best === null || row[k] > row[best]) best = k;
|
|
58
|
+
return best !== null && total >= min && row[best] / total >= threshold ? best : null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/prefetch.ts
|
|
62
|
+
var KEY = "vitral:prefetch";
|
|
63
|
+
function slow() {
|
|
64
|
+
const c = navigator.connection;
|
|
65
|
+
return !!c?.saveData || /2g/.test(c?.effectiveType ?? "");
|
|
66
|
+
}
|
|
67
|
+
var idle = (fn) => typeof requestIdleCallback === "function" ? requestIdleCallback(fn, { timeout: 3e3 }) : setTimeout(fn, 300);
|
|
68
|
+
function prefetch(options = {}) {
|
|
69
|
+
if (typeof window === "undefined") return () => {
|
|
70
|
+
};
|
|
71
|
+
const { threshold = 0.4, min = 2, key = (u) => u.pathname, onPrefetch } = options;
|
|
72
|
+
let storage = options.storage;
|
|
73
|
+
if (storage === void 0)
|
|
74
|
+
try {
|
|
75
|
+
storage = localStorage;
|
|
76
|
+
} catch {
|
|
77
|
+
storage = null;
|
|
78
|
+
}
|
|
79
|
+
let chain = empty();
|
|
80
|
+
try {
|
|
81
|
+
chain = parse(storage?.getItem(KEY));
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
const save = () => {
|
|
85
|
+
try {
|
|
86
|
+
storage?.setItem(KEY, JSON.stringify(chain));
|
|
87
|
+
} catch {
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const here = () => key(new URL(location.href));
|
|
91
|
+
let current = here();
|
|
92
|
+
const loaded = /* @__PURE__ */ new Set();
|
|
93
|
+
let seq = 0;
|
|
94
|
+
const schedule = () => {
|
|
95
|
+
const id = ++seq;
|
|
96
|
+
if (slow()) return;
|
|
97
|
+
idle(() => {
|
|
98
|
+
const next = id === seq && predict(chain, current, threshold, min);
|
|
99
|
+
if (!next) return;
|
|
100
|
+
const names = (chain.r[next] ?? []).filter((n) => !loaded.has(n));
|
|
101
|
+
if (!names.length) return;
|
|
102
|
+
for (const n of names) loaded.add(n);
|
|
103
|
+
Promise.all(names.map(warm)).then((ok2) => {
|
|
104
|
+
const done = names.filter((_, i) => ok2[i]);
|
|
105
|
+
if (done.length) onPrefetch?.(done, next);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const visit = () => {
|
|
110
|
+
const next = here();
|
|
111
|
+
if (next === current) return;
|
|
112
|
+
record(chain, current, next);
|
|
113
|
+
current = next;
|
|
114
|
+
save();
|
|
115
|
+
schedule();
|
|
116
|
+
};
|
|
117
|
+
let observer;
|
|
118
|
+
try {
|
|
119
|
+
observer = new PerformanceObserver((list) => {
|
|
120
|
+
visit();
|
|
121
|
+
let changed = false;
|
|
122
|
+
for (const e of list.getEntries()) {
|
|
123
|
+
const m = /^vitral:(.+):mount$/.exec(e.name);
|
|
124
|
+
if (!m) continue;
|
|
125
|
+
loaded.add(m[1]);
|
|
126
|
+
changed = remember(chain, current, m[1]) || changed;
|
|
127
|
+
}
|
|
128
|
+
if (changed) save();
|
|
129
|
+
});
|
|
130
|
+
observer.observe({ type: "measure", buffered: true });
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
const nav = globalThis.navigation;
|
|
134
|
+
const event = nav ? "currententrychange" : "popstate";
|
|
135
|
+
const target = nav ?? window;
|
|
136
|
+
target.addEventListener(event, visit);
|
|
137
|
+
schedule();
|
|
138
|
+
return () => {
|
|
139
|
+
seq++;
|
|
140
|
+
observer?.disconnect();
|
|
141
|
+
target.removeEventListener(event, visit);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
var heat = (u) => fetch(u, { priority: "low" }).then((res) => res.arrayBuffer());
|
|
145
|
+
function modulepreload(href) {
|
|
146
|
+
return new Promise((resolve, reject) => {
|
|
147
|
+
const link = addLink("modulepreload", href, { fetchPriority: "low" });
|
|
148
|
+
link.onload = resolve;
|
|
149
|
+
link.onerror = reject;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
async function verifiedOnly(r) {
|
|
153
|
+
const b = r.split ?? { entry: r.entry, chunks: [], sri: { [r.entry]: r.integrity }, priority: "low" };
|
|
154
|
+
const { verified } = await import("./sri-576GTDIA.js");
|
|
155
|
+
const url = await verified(b);
|
|
156
|
+
if (!url) await Promise.all([...b.chunks, b.entry].map(heat));
|
|
157
|
+
else if (!document.querySelector(`link[rel=modulepreload][href="${CSS.escape(url)}"]`)) await heat(url);
|
|
158
|
+
}
|
|
159
|
+
async function warm(name) {
|
|
160
|
+
try {
|
|
161
|
+
const p = protocol();
|
|
162
|
+
await p.pending();
|
|
163
|
+
let n = name;
|
|
164
|
+
while (n && !p.entry(n)) n = n.slice(0, Math.max(0, n.lastIndexOf("/")));
|
|
165
|
+
const entry = p.entry(n);
|
|
166
|
+
if (!entry?.url || (entry.isolate ?? p.settings().isolate) === "iframe") return false;
|
|
167
|
+
const r = await resolveEntry(n, entry, "low");
|
|
168
|
+
const css = r.css.map(heat);
|
|
169
|
+
await Promise.all([r.integrity ? verifiedOnly(r) : modulepreload(r.entry), ...css]);
|
|
170
|
+
return true;
|
|
171
|
+
} catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export {
|
|
176
|
+
prefetch,
|
|
177
|
+
warm
|
|
178
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { P as Props } from './types-DUtcF3HO.js';
|
|
3
|
+
import './errors-kjBv6IH_.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SSR de um remote React, para o `render` do gateway (`vitral/edge`):
|
|
7
|
+
*
|
|
8
|
+
* // carrinho/src/server.ts
|
|
9
|
+
* import { reactRender } from 'vitral/react-server'
|
|
10
|
+
* import Carrinho from './Carrinho'
|
|
11
|
+
* export const render = reactRender(Carrinho)
|
|
12
|
+
*
|
|
13
|
+
* No navegador, `reactRemote` (ou o plugin, que embrulha sozinho) hidrata
|
|
14
|
+
* esse HTML. No servidor, `useVitral()` devolve `null`.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** `render(props)` do gateway para um componente React. */
|
|
18
|
+
declare function reactRender<P extends Props>(Component: ComponentType<P>): (props: P) => string;
|
|
19
|
+
|
|
20
|
+
export { reactRender };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RemoteTree
|
|
3
|
+
} from "./chunk-B2MPYF4M.js";
|
|
4
|
+
|
|
5
|
+
// src/react-server.tsx
|
|
6
|
+
import { renderToString } from "react-dom/server";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
function reactRender(Component) {
|
|
9
|
+
return (props) => renderToString(/* @__PURE__ */ jsx(RemoteTree, { Component, props, ctx: null }));
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
reactRender
|
|
13
|
+
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ReactNode, ComponentType } from 'react';
|
|
2
2
|
import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
|
|
3
3
|
import * as JSXRuntime from 'react/jsx-runtime';
|
|
4
|
-
import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared, R as RemoteContext } from './types-
|
|
5
|
-
export { E as EventBus } from './types-
|
|
6
|
-
export { e as events } from './events-
|
|
4
|
+
import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared, R as RemoteContext } from './types-DUtcF3HO.js';
|
|
5
|
+
export { E as EventBus } from './types-DUtcF3HO.js';
|
|
6
|
+
export { e as events } from './events-0rxFlWJJ.js';
|
|
7
7
|
import './errors-kjBv6IH_.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -14,7 +14,10 @@ import './errors-kjBv6IH_.js';
|
|
|
14
14
|
* Remote: export default reactRemote(App)
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Transforma um componente React em um remote. Com o HTML do servidor
|
|
19
|
+
* (`reactRender` de `vitral/react-server`, no gateway), hidrata em vez de montar.
|
|
20
|
+
*/
|
|
18
21
|
declare function reactRemote<P extends Props>(Component: ComponentType<P>): RemoteModule<P>;
|
|
19
22
|
/** Dentro de um remote: dá acesso ao contexto (nome, eventos, baseUrl). */
|
|
20
23
|
declare function useVitral(): RemoteContext | null;
|
package/dist/react.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
RemoteTree,
|
|
4
|
+
VitralContext
|
|
5
|
+
} from "./chunk-B2MPYF4M.js";
|
|
2
6
|
import {
|
|
3
7
|
hostSlot
|
|
4
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UXLKRSOM.js";
|
|
5
9
|
import {
|
|
6
10
|
defineRemote,
|
|
7
11
|
events,
|
|
8
12
|
memoSelect,
|
|
9
13
|
same,
|
|
10
14
|
shared
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-HIVMSPGM.js";
|
|
16
|
+
import "./chunk-S7PIVPBX.js";
|
|
17
|
+
import "./chunk-KU6HF2EW.js";
|
|
14
18
|
import "./chunk-TW7KYJQ6.js";
|
|
15
19
|
import "./chunk-463H6B56.js";
|
|
16
20
|
import {
|
|
@@ -19,8 +23,6 @@ import {
|
|
|
19
23
|
|
|
20
24
|
// src/react.tsx
|
|
21
25
|
import {
|
|
22
|
-
Component as ReactComponent,
|
|
23
|
-
createContext,
|
|
24
26
|
useContext,
|
|
25
27
|
useEffect,
|
|
26
28
|
useMemo,
|
|
@@ -28,39 +30,25 @@ import {
|
|
|
28
30
|
useState,
|
|
29
31
|
useSyncExternalStore
|
|
30
32
|
} from "react";
|
|
31
|
-
import { createRoot } from "react-dom/client";
|
|
33
|
+
import { createRoot, hydrateRoot } from "react-dom/client";
|
|
32
34
|
import * as ReactAll from "react";
|
|
33
35
|
import * as ReactDOM from "react-dom";
|
|
34
36
|
import * as ReactDOMClient from "react-dom/client";
|
|
35
37
|
import * as JSXRuntime from "react/jsx-runtime";
|
|
36
38
|
import * as JSXDevRuntime from "react/jsx-dev-runtime";
|
|
37
39
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
38
|
-
var VitralContext = createContext(null);
|
|
39
|
-
var Boundary = class extends ReactComponent {
|
|
40
|
-
constructor() {
|
|
41
|
-
super(...arguments);
|
|
42
|
-
this.state = { failed: false };
|
|
43
|
-
}
|
|
44
|
-
static getDerivedStateFromError() {
|
|
45
|
-
return { failed: true };
|
|
46
|
-
}
|
|
47
|
-
componentDidCatch(error) {
|
|
48
|
-
this.props.ctx.reportError(error);
|
|
49
|
-
}
|
|
50
|
-
render() {
|
|
51
|
-
return this.state.failed ? null : this.props.children;
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
40
|
function reactRemote(Component) {
|
|
41
|
+
const start = (el, props, ctx, hydrate) => {
|
|
42
|
+
const tree = (p) => /* @__PURE__ */ jsx(RemoteTree, { Component, props: p, ctx });
|
|
43
|
+
const options = { onUncaughtError: (e) => ctx.reportError(e) };
|
|
44
|
+
const root = hydrate ? hydrateRoot(el, tree(props), options) : createRoot(el, options);
|
|
45
|
+
const render = (p) => root.render(tree(p));
|
|
46
|
+
if (!hydrate) render(props);
|
|
47
|
+
return { update: render, unmount: () => root.unmount() };
|
|
48
|
+
};
|
|
55
49
|
return defineRemote({
|
|
56
|
-
mount(el, props, ctx)
|
|
57
|
-
|
|
58
|
-
const render = (p) => root.render(
|
|
59
|
-
/* @__PURE__ */ jsx(VitralContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx(Boundary, { ctx, children: /* @__PURE__ */ jsx(Component, { ...p }) }) })
|
|
60
|
-
);
|
|
61
|
-
render(props);
|
|
62
|
-
return { update: render, unmount: () => root.unmount() };
|
|
63
|
-
}
|
|
50
|
+
mount: (el, props, ctx) => start(el, props, ctx, false),
|
|
51
|
+
hydrate: (el, props, ctx) => start(el, props, ctx, true)
|
|
64
52
|
});
|
|
65
53
|
}
|
|
66
54
|
function useVitral() {
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import {
|
|
2
|
+
splitName
|
|
3
|
+
} from "./chunk-JBNITHPI.js";
|
|
4
|
+
import {
|
|
5
|
+
verifyIntegrity
|
|
6
|
+
} from "./chunk-UYOPJ4XQ.js";
|
|
7
|
+
import {
|
|
8
|
+
resolveEntry
|
|
9
|
+
} from "./chunk-S7PIVPBX.js";
|
|
10
|
+
import {
|
|
11
|
+
prefetchCss
|
|
12
|
+
} from "./chunk-KU6HF2EW.js";
|
|
13
|
+
import {
|
|
14
|
+
fetchBytes,
|
|
15
|
+
metric,
|
|
16
|
+
withRetry,
|
|
17
|
+
withTimeout
|
|
18
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
19
|
+
import {
|
|
20
|
+
RemoteError,
|
|
21
|
+
isRemoteError,
|
|
22
|
+
report
|
|
23
|
+
} from "./chunk-463H6B56.js";
|
|
24
|
+
import {
|
|
25
|
+
protocol
|
|
26
|
+
} from "./chunk-GNPFWISJ.js";
|
|
27
|
+
|
|
28
|
+
// src/core/reframe.ts
|
|
29
|
+
var REFRAME_SCRIPT = "window.__vitral=function(u){return import(u)}";
|
|
30
|
+
var OWN = /^(popstate|hashchange|message|messageerror|error|unhandledrejection|rejectionhandled)$/;
|
|
31
|
+
var VIEW = ["innerWidth", "innerHeight", "outerWidth", "outerHeight", "devicePixelRatio", "scrollX", "scrollY", "pageXOffset", "pageYOffset", "screenX", "screenY", "visualViewport"];
|
|
32
|
+
var VIEW_FNS = ["matchMedia", "scrollTo", "scroll", "scrollBy", "getComputedStyle", "getSelection"];
|
|
33
|
+
var DOC_FNS = ["createElementNS", "createTextNode", "createComment", "createDocumentFragment", "createEvent", "createRange", "createTreeWalker", "createNodeIterator", "createAttribute", "importNode", "adoptNode", "getSelection"];
|
|
34
|
+
var set = (o, values) => {
|
|
35
|
+
for (const k in values) Object.defineProperty(o, k, { configurable: true, writable: true, value: values[k] });
|
|
36
|
+
};
|
|
37
|
+
var get = (o, getters) => {
|
|
38
|
+
for (const k in getters) Object.defineProperty(o, k, { configurable: true, get: getters[k] });
|
|
39
|
+
};
|
|
40
|
+
async function load(name, _isolate, priority) {
|
|
41
|
+
const p = protocol();
|
|
42
|
+
const { timeout, retries } = p.settings();
|
|
43
|
+
const [remote, key] = splitName(name);
|
|
44
|
+
let resolved;
|
|
45
|
+
let realm;
|
|
46
|
+
try {
|
|
47
|
+
const entry = p.entry(remote);
|
|
48
|
+
if (!entry) throw new RemoteError("NOT_REGISTERED", name, "remote n\xE3o registrado. Use configure({ remotes }).");
|
|
49
|
+
if (!entry.url) throw new RemoteError("MOUNT_FAILED", name, "remote local (module) n\xE3o roda com isolate: 'reframe': registre a URL dele");
|
|
50
|
+
let t = performance.now();
|
|
51
|
+
const { integrity, ...r } = await resolveEntry(remote, entry, priority);
|
|
52
|
+
delete r.split;
|
|
53
|
+
resolved = r;
|
|
54
|
+
metric(name, "manifest", t);
|
|
55
|
+
prefetchCss(r, true, priority);
|
|
56
|
+
t = performance.now();
|
|
57
|
+
const bytes = integrity && await withRetry(retries, async () => {
|
|
58
|
+
const b = await fetchBytes(r.entry, timeout, name, { priority });
|
|
59
|
+
await verifyIntegrity(name, b, integrity);
|
|
60
|
+
return b;
|
|
61
|
+
});
|
|
62
|
+
const url = bytes ? URL.createObjectURL(new Blob([bytes], { type: "text/javascript" })) : r.entry;
|
|
63
|
+
const { registryFor } = await import("./shadow-S4SKHTA7.js");
|
|
64
|
+
realm = createRealm(r.name ?? name, registryFor(r.name ?? name));
|
|
65
|
+
let ns;
|
|
66
|
+
try {
|
|
67
|
+
ns = await withTimeout(timeout, name, realm.load(url));
|
|
68
|
+
} catch (e) {
|
|
69
|
+
throw isRemoteError(e) ? e : new RemoteError("LOAD_FAILED", name, `falha ao importar ${r.entry}`, e);
|
|
70
|
+
} finally {
|
|
71
|
+
if (bytes) URL.revokeObjectURL(url);
|
|
72
|
+
}
|
|
73
|
+
if (key) {
|
|
74
|
+
const part = ns?.exposes?.[key];
|
|
75
|
+
if (!part) throw new RemoteError("NOT_EXPOSED", name, `${remote} n\xE3o exp\xF5e ${key}`);
|
|
76
|
+
ns = typeof part === "function" ? await part() : part;
|
|
77
|
+
}
|
|
78
|
+
const mod = ns?.default ?? ns;
|
|
79
|
+
if (typeof mod?.mount != "function") throw new RemoteError("INVALID_MODULE", name, "o m\xF3dulo n\xE3o exporta mount()");
|
|
80
|
+
metric(name, "js", t);
|
|
81
|
+
const own = realm;
|
|
82
|
+
return { ...r, module: { mount: (el, props, ctx) => own.mount(mod, el, props, ctx) } };
|
|
83
|
+
} catch (e) {
|
|
84
|
+
realm?.dispose();
|
|
85
|
+
throw report(isRemoteError(e) ? e : new RemoteError("LOAD_FAILED", name, String(e?.message ?? e), e), resolved);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function noFrames(_target, name) {
|
|
89
|
+
return Promise.reject(new RemoteError("MOUNT_FAILED", name, 'isolate="iframe" precisa de enableIframe(), de vitral/iframe'));
|
|
90
|
+
}
|
|
91
|
+
function createRealm(name, registry) {
|
|
92
|
+
const host = document;
|
|
93
|
+
const frame = host.createElement("iframe");
|
|
94
|
+
frame.setAttribute("data-vitral-reframe", name);
|
|
95
|
+
frame.setAttribute("aria-hidden", "true");
|
|
96
|
+
frame.tabIndex = -1;
|
|
97
|
+
frame.style.display = "none";
|
|
98
|
+
host.body.appendChild(frame);
|
|
99
|
+
const w = frame.contentWindow;
|
|
100
|
+
const d = w.document;
|
|
101
|
+
d.open();
|
|
102
|
+
d.close();
|
|
103
|
+
const realHead = d.head;
|
|
104
|
+
const inFrame = d.createElement.bind(d);
|
|
105
|
+
const script = d.createElement("script");
|
|
106
|
+
script.nonce = host.querySelector("script[nonce]")?.nonce ?? "";
|
|
107
|
+
script.textContent = REFRAME_SCRIPT;
|
|
108
|
+
realHead.appendChild(script);
|
|
109
|
+
const load2 = w.__vitral;
|
|
110
|
+
delete w.__vitral;
|
|
111
|
+
const head = host.createElement("div");
|
|
112
|
+
head.setAttribute("data-vitral-head", "");
|
|
113
|
+
head.hidden = true;
|
|
114
|
+
let root = null;
|
|
115
|
+
let body = head;
|
|
116
|
+
let ctx = null;
|
|
117
|
+
const scope = () => root ?? head;
|
|
118
|
+
const ctrl = new AbortController();
|
|
119
|
+
const listen = (target, own) => {
|
|
120
|
+
const add = own?.addEventListener;
|
|
121
|
+
const remove = own?.removeEventListener;
|
|
122
|
+
return {
|
|
123
|
+
addEventListener(type, fn, o) {
|
|
124
|
+
if (own && OWN.test(type)) return add.call(own, type, fn, o);
|
|
125
|
+
const opts = typeof o == "object" ? o : { capture: !!o };
|
|
126
|
+
const signal = opts.signal && AbortSignal.any ? AbortSignal.any([opts.signal, ctrl.signal]) : ctrl.signal;
|
|
127
|
+
target.addEventListener(type, fn, { ...opts, signal });
|
|
128
|
+
},
|
|
129
|
+
removeEventListener(type, fn, o) {
|
|
130
|
+
if (own && OWN.test(type)) return remove.call(own, type, fn, o);
|
|
131
|
+
target.removeEventListener(type, fn, o);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
const scoped = Object.getPrototypeOf(registry) !== customElements;
|
|
136
|
+
const createElement = (tag, o) => {
|
|
137
|
+
if (/^script$/i.test(tag)) return inFrame(tag);
|
|
138
|
+
if (scoped && !o?.customElementRegistry)
|
|
139
|
+
try {
|
|
140
|
+
return host.createElement(tag, { ...o, customElementRegistry: registry });
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
return host.createElement(tag, o);
|
|
144
|
+
};
|
|
145
|
+
const fromHost = {};
|
|
146
|
+
for (const k of DOC_FNS) fromHost[k] = host[k].bind(host);
|
|
147
|
+
set(d, {
|
|
148
|
+
...fromHost,
|
|
149
|
+
...listen(host, null),
|
|
150
|
+
createElement,
|
|
151
|
+
querySelector: (s) => scope().querySelector(s),
|
|
152
|
+
querySelectorAll: (s) => scope().querySelectorAll(s),
|
|
153
|
+
getElementById: (id) => scope().querySelector(`#${CSS.escape(id)}`),
|
|
154
|
+
getElementsByClassName: (c) => scope().querySelectorAll(c.trim().split(/\s+/).map((x) => "." + CSS.escape(x)).join("")),
|
|
155
|
+
getElementsByTagName: (t) => scope().querySelectorAll(t),
|
|
156
|
+
getElementsByName: (n) => scope().querySelectorAll(`[name="${CSS.escape(n)}"]`),
|
|
157
|
+
elementFromPoint: (x, y) => (root ?? host).elementFromPoint(x, y),
|
|
158
|
+
elementsFromPoint: (x, y) => (root ?? host).elementsFromPoint(x, y)
|
|
159
|
+
});
|
|
160
|
+
get(d, {
|
|
161
|
+
head: () => head,
|
|
162
|
+
body: () => body,
|
|
163
|
+
documentElement: () => host.documentElement,
|
|
164
|
+
activeElement: () => root?.activeElement ?? host.body
|
|
165
|
+
});
|
|
166
|
+
const redirect = (el) => {
|
|
167
|
+
const append = el.appendChild;
|
|
168
|
+
const before = el.insertBefore;
|
|
169
|
+
set(el, {
|
|
170
|
+
appendChild: (n) => n.nodeName == "SCRIPT" ? realHead.appendChild(n) : append.call(el, n),
|
|
171
|
+
insertBefore: (n, ref) => n.nodeName == "SCRIPT" ? realHead.appendChild(n) : before.call(el, n, ref)
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
redirect(head);
|
|
175
|
+
const view = {};
|
|
176
|
+
for (const k of VIEW) view[k] = () => window[k];
|
|
177
|
+
get(w, view);
|
|
178
|
+
const viewFns = {};
|
|
179
|
+
for (const k of VIEW_FNS) viewFns[k] = window[k].bind(window);
|
|
180
|
+
set(w, { ...viewFns, ...listen(window, w), HTMLElement, customElements: registry });
|
|
181
|
+
w.addEventListener("error", (e) => ctx?.reportError(e.error ?? e.message));
|
|
182
|
+
w.addEventListener("unhandledrejection", (e) => ctx?.reportError(e.reason));
|
|
183
|
+
const h = w.history;
|
|
184
|
+
const push = h.pushState;
|
|
185
|
+
const replace = h.replaceState;
|
|
186
|
+
const go = (fn, method) => (state, title, url) => {
|
|
187
|
+
fn.call(h, state, title, url);
|
|
188
|
+
const href = w.location.href;
|
|
189
|
+
if (href === location.href) return;
|
|
190
|
+
history[method](state, "", href);
|
|
191
|
+
dispatchEvent(new PopStateEvent("popstate", { state }));
|
|
192
|
+
protocol().events.emit("vitral:navigate", location.pathname + location.search + location.hash);
|
|
193
|
+
};
|
|
194
|
+
set(h, { pushState: go(push, "pushState"), replaceState: go(replace, "replaceState") });
|
|
195
|
+
const pull = () => {
|
|
196
|
+
const old = w.location.href;
|
|
197
|
+
if (old === location.href) return;
|
|
198
|
+
try {
|
|
199
|
+
replace.call(h, history.state, "", location.href);
|
|
200
|
+
} catch {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
w.dispatchEvent(new w.PopStateEvent("popstate", { state: history.state }));
|
|
204
|
+
if (old.split("#")[1] !== location.href.split("#")[1]) w.dispatchEvent(new w.HashChangeEvent("hashchange", { oldURL: old, newURL: location.href }));
|
|
205
|
+
};
|
|
206
|
+
addEventListener("popstate", pull, { signal: ctrl.signal });
|
|
207
|
+
globalThis.navigation?.addEventListener("currententrychange", pull, { signal: ctrl.signal });
|
|
208
|
+
const dispose = () => {
|
|
209
|
+
ctx = null;
|
|
210
|
+
ctrl.abort();
|
|
211
|
+
head.remove();
|
|
212
|
+
frame.remove();
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
load: (url) => {
|
|
216
|
+
if (!load2) throw new RemoteError("LOAD_FAILED", name, "a CSP bloqueou o script do iframe do isolate: 'reframe' (libere o hash de REFRAME_SCRIPT ou use nonce)");
|
|
217
|
+
return load2(url);
|
|
218
|
+
},
|
|
219
|
+
async mount(mod, el, props, c) {
|
|
220
|
+
ctx = c;
|
|
221
|
+
root = c.shadowRoot;
|
|
222
|
+
if (root) root.prepend(head);
|
|
223
|
+
body = c.portalContainer ?? el;
|
|
224
|
+
if (body !== head) redirect(body);
|
|
225
|
+
pull();
|
|
226
|
+
let handle;
|
|
227
|
+
try {
|
|
228
|
+
handle = await mod.mount(el, props, c);
|
|
229
|
+
} catch (e) {
|
|
230
|
+
dispose();
|
|
231
|
+
throw e;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
update: (next) => handle.update?.(next),
|
|
235
|
+
unmount() {
|
|
236
|
+
try {
|
|
237
|
+
handle.unmount();
|
|
238
|
+
} finally {
|
|
239
|
+
dispose();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
},
|
|
244
|
+
dispose
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
export {
|
|
248
|
+
REFRAME_SCRIPT,
|
|
249
|
+
load,
|
|
250
|
+
noFrames
|
|
251
|
+
};
|
package/dist/routes.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { R as Routes, a as RouteMatch } from './match-CMBM_jLW.js';
|
|
2
|
+
import { P as Props } from './types-DUtcF3HO.js';
|
|
3
|
+
import { S as SlotStatus } from './slot-D49L1rdU.js';
|
|
3
4
|
import './errors-kjBv6IH_.js';
|
|
4
5
|
|
|
5
|
-
/** Padrão de URL → nome do remote. A primeira rota que bate vence. */
|
|
6
|
-
type Routes = Record<string, string>;
|
|
7
6
|
interface RoutesOptions {
|
|
8
7
|
/**
|
|
9
8
|
* Links `<a href>` da mesma origem que batem com uma rota navegam sem
|
|
@@ -11,14 +10,6 @@ interface RoutesOptions {
|
|
|
11
10
|
*/
|
|
12
11
|
links?: boolean;
|
|
13
12
|
}
|
|
14
|
-
interface RouteMatch {
|
|
15
|
-
/** Nome do remote. */
|
|
16
|
-
name: string;
|
|
17
|
-
/** Padrão que bateu. */
|
|
18
|
-
pattern: string;
|
|
19
|
-
/** Segmentos `:nome` do padrão. */
|
|
20
|
-
params: Record<string, string>;
|
|
21
|
-
}
|
|
22
13
|
/**
|
|
23
14
|
* Remote da rota que bate com `path`, ou `null`. Padrões: `/conta` (exato),
|
|
24
15
|
* `/checkout/*` (o prefixo e tudo abaixo dele), `/produto/:id` e `*` (qualquer).
|
|
@@ -53,4 +44,4 @@ declare global {
|
|
|
53
44
|
}
|
|
54
45
|
}
|
|
55
46
|
|
|
56
|
-
export {
|
|
47
|
+
export { RouteMatch, Routes, type RoutesOptions, VitralOutletElement, defineVitralOutlet, matchRoute, routes };
|