vitral 0.3.0 → 0.5.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-IHTUM6LT.js → chunk-4Z77XNBR.js} +2 -2
- package/dist/chunk-54CBIZES.js +105 -0
- package/dist/{chunk-TD4S3IHA.js → chunk-5JNV45BB.js} +10 -8
- package/dist/{chunk-SDB5AZEI.js → chunk-C3QOBAUE.js} +2 -2
- package/dist/chunk-DAESKNQ6.js +207 -0
- package/dist/{chunk-3YXI3G34.js → chunk-K6EG7DMO.js} +16 -7
- package/dist/{chunk-ZAC6QQI6.js → chunk-KU6HF2EW.js} +4 -4
- package/dist/{chunk-I3VSKSAZ.js → chunk-KZBH5MPD.js} +29 -27
- package/dist/chunk-NZEQGRBL.js +93 -0
- package/dist/chunk-PY7P5BF4.js +404 -0
- package/dist/{chunk-GNHCZRQP.js → chunk-TW7KYJQ6.js} +1 -1
- package/dist/{chunk-AH7KNMBW.js → chunk-UYOPJ4XQ.js} +1 -1
- package/dist/cli.js +1522 -37
- package/dist/devtools.d.ts +32 -2
- package/dist/devtools.js +27 -12
- package/dist/dict.d.ts +69 -0
- package/dist/dict.js +8 -0
- package/dist/edge.d.ts +118 -0
- package/dist/edge.js +398 -0
- 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-0rxFlWJJ.d.ts} +1 -1
- package/dist/expose-IAKYHJXF.js +15 -0
- package/dist/federation.d.ts +89 -0
- package/dist/federation.js +101 -0
- package/dist/hydrate-YVZDJ2V7.js +168 -0
- package/dist/iframe.js +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/otel.d.ts +29 -1
- package/dist/otel.js +13 -1
- package/dist/overrides-NP754HY7.js +27 -0
- package/dist/preact.d.ts +4 -4
- package/dist/preact.js +6 -6
- package/dist/prefetch.d.ts +25 -0
- package/dist/prefetch.js +178 -0
- package/dist/react.d.ts +3 -3
- package/dist/react.js +6 -6
- package/dist/reframe-LQL4DZYP.js +251 -0
- package/dist/routes.d.ts +2 -2
- package/dist/routes.js +5 -5
- package/dist/{shadow-6HELCHCJ.js → shadow-S4SKHTA7.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-D49L1rdU.d.ts} +1 -1
- package/dist/solid.d.ts +3 -3
- package/dist/solid.js +6 -6
- package/dist/{sri-JMX6JLQP.js → sri-576GTDIA.js} +41 -10
- package/dist/svelte.d.ts +4 -4
- package/dist/svelte.js +6 -6
- package/dist/testing.d.ts +171 -3
- package/dist/testing.js +193 -6
- package/dist/{types-Czvm-siZ.d.ts → types-DUtcF3HO.d.ts} +124 -5
- package/dist/vitals.d.ts +29 -0
- package/dist/vitals.js +152 -0
- package/dist/vite.d.ts +18 -0
- package/dist/vite.js +329 -417
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +6 -6
- package/package.json +170 -21
- package/dist/chunk-DXORSF4X.js +0 -42
- package/dist/expose-JUOUN5N5.js +0 -15
- package/dist/overrides-NZAIUGK5.js +0 -15
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// src/federation.ts
|
|
2
|
+
var containers = /* @__PURE__ */ new Map();
|
|
3
|
+
var fail = (msg) => new Error(`[vitral] ${msg}`);
|
|
4
|
+
var key = (k) => "./" + k.replace(/^\.?\/?/, "");
|
|
5
|
+
function federationRemote(url, options = {}) {
|
|
6
|
+
return { module: () => namespace(url, options) };
|
|
7
|
+
}
|
|
8
|
+
async function namespace(url, options) {
|
|
9
|
+
const { container, keys } = await loadContainer(new URL(url, document.baseURI).href, options);
|
|
10
|
+
const parts = /* @__PURE__ */ new Map();
|
|
11
|
+
const part = (k) => {
|
|
12
|
+
let p = parts.get(k);
|
|
13
|
+
if (!p) {
|
|
14
|
+
p = Promise.resolve(container.get(k)).then((factory) => adapted(factory(), k, options));
|
|
15
|
+
p.catch(() => parts.delete(k));
|
|
16
|
+
parts.set(k, p);
|
|
17
|
+
}
|
|
18
|
+
return p;
|
|
19
|
+
};
|
|
20
|
+
const exposes = keys ? Object.fromEntries(keys.map((k) => [k, () => part(k)])) : new Proxy({}, { get: (_, k) => typeof k == "string" && k.startsWith("./") ? () => part(k) : void 0 });
|
|
21
|
+
const main = options.expose ? key(options.expose) : keys?.length === 1 ? keys[0] : void 0;
|
|
22
|
+
const remote = {
|
|
23
|
+
async mount(el, props, ctx) {
|
|
24
|
+
if (!main) throw fail(`${ctx.name}: o manifesto exp\xF5e ${keys?.join(", ") || "v\xE1rias partes"}. Use ${ctx.name}/<parte> ou a op\xE7\xE3o expose.`);
|
|
25
|
+
const ns = await part(main);
|
|
26
|
+
const target = typeof ns?.mount == "function" ? ns : ns?.default;
|
|
27
|
+
if (typeof target?.mount != "function") throw fail(`${ctx.name}: ${main} n\xE3o exporta mount(). Use a op\xE7\xE3o adapt de federationRemote.`);
|
|
28
|
+
return target.mount(el, props, ctx);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return { default: remote, exposes };
|
|
32
|
+
}
|
|
33
|
+
function adapted(ns, k, options) {
|
|
34
|
+
if (typeof ns?.mount == "function" || typeof ns?.default?.mount == "function" || !options.adapt) return ns;
|
|
35
|
+
const remote = options.adapt(ns, k);
|
|
36
|
+
return typeof remote?.mount == "function" ? { ...ns, default: remote } : ns;
|
|
37
|
+
}
|
|
38
|
+
function loadContainer(url, options = {}) {
|
|
39
|
+
let job = containers.get(url);
|
|
40
|
+
if (!job) {
|
|
41
|
+
job = start(url, options);
|
|
42
|
+
job.catch(() => containers.delete(url));
|
|
43
|
+
containers.set(url, job);
|
|
44
|
+
}
|
|
45
|
+
return job;
|
|
46
|
+
}
|
|
47
|
+
async function start(url, options) {
|
|
48
|
+
let entry = url;
|
|
49
|
+
let global = options.global;
|
|
50
|
+
let keys = null;
|
|
51
|
+
if (new URL(url).pathname.endsWith(".json")) {
|
|
52
|
+
const res = await fetch(url, { cache: "no-cache" });
|
|
53
|
+
if (!res.ok) throw fail(`HTTP ${res.status} ao baixar ${url}`);
|
|
54
|
+
const m = await res.json();
|
|
55
|
+
const re = m.metaData?.remoteEntry;
|
|
56
|
+
if (!re?.name) throw fail(`${url} n\xE3o \xE9 um mf-manifest.json (falta metaData.remoteEntry)`);
|
|
57
|
+
const pub = m.metaData.publicPath;
|
|
58
|
+
if ((!pub || pub === "auto") && m.metaData.getPublicPath) throw fail(`${url}: getPublicPath n\xE3o \xE9 suportado. Use publicPath.`);
|
|
59
|
+
const base = pub && pub !== "auto" ? new URL(pub, url).href : url;
|
|
60
|
+
entry = new URL((re.path ? re.path.replace(/\/?$/, "/") : "") + re.name, base).href;
|
|
61
|
+
global = re.type === "module" || re.type === "esm" ? void 0 : m.metaData.globalName ?? m.name;
|
|
62
|
+
if (re.type !== "module" && re.type !== "esm" && !global) throw fail(`${url}: falta metaData.globalName`);
|
|
63
|
+
keys = (m.exposes ?? []).map((e) => key(e.path));
|
|
64
|
+
}
|
|
65
|
+
const origin = new URL(entry).origin;
|
|
66
|
+
const allowed = [new URL(url).origin, ...options.allowedOrigins ?? []];
|
|
67
|
+
if (!allowed.includes("*") && !allowed.includes(origin)) throw fail(`remoteEntry em ${origin} n\xE3o est\xE1 em allowedOrigins`);
|
|
68
|
+
const container = global ? await script(entry, global) : await import(
|
|
69
|
+
/* @vite-ignore */
|
|
70
|
+
/* webpackIgnore: true */
|
|
71
|
+
entry
|
|
72
|
+
);
|
|
73
|
+
if (typeof container?.get != "function" || typeof container.init != "function") throw fail(`${entry} n\xE3o \xE9 um container do Module Federation (sem get/init)`);
|
|
74
|
+
await container.init(shareScope(options.shared));
|
|
75
|
+
return { container, keys };
|
|
76
|
+
}
|
|
77
|
+
function shareScope(shared = {}) {
|
|
78
|
+
const out = {};
|
|
79
|
+
for (const { version, modules } of Object.values(shared)) {
|
|
80
|
+
for (const [spec, mod] of Object.entries(modules)) (out[spec] ??= {})[version] = { get: () => Promise.resolve(() => mod), loaded: 1, from: "vitral" };
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
function script(src, global) {
|
|
85
|
+
const w = window;
|
|
86
|
+
if (w[global]) return Promise.resolve(w[global]);
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const s = document.createElement("script");
|
|
89
|
+
s.src = src;
|
|
90
|
+
s.onload = () => w[global] ? resolve(w[global]) : reject(fail(`${src} n\xE3o criou window.${global}`));
|
|
91
|
+
s.onerror = () => {
|
|
92
|
+
s.remove();
|
|
93
|
+
reject(fail(`falha ao carregar ${src}`));
|
|
94
|
+
};
|
|
95
|
+
document.head.appendChild(s);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export {
|
|
99
|
+
federationRemote,
|
|
100
|
+
shareScope
|
|
101
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hostSlot
|
|
3
|
+
} from "./chunk-4Z77XNBR.js";
|
|
4
|
+
import {
|
|
5
|
+
mountOnce,
|
|
6
|
+
navigate,
|
|
7
|
+
refreshable,
|
|
8
|
+
registered,
|
|
9
|
+
scopedEvents,
|
|
10
|
+
track
|
|
11
|
+
} from "./chunk-KZBH5MPD.js";
|
|
12
|
+
import {
|
|
13
|
+
load
|
|
14
|
+
} from "./chunk-5JNV45BB.js";
|
|
15
|
+
import {
|
|
16
|
+
injectStyles
|
|
17
|
+
} from "./chunk-KU6HF2EW.js";
|
|
18
|
+
import {
|
|
19
|
+
metric
|
|
20
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
21
|
+
import {
|
|
22
|
+
RemoteError,
|
|
23
|
+
ctxHooks,
|
|
24
|
+
isRemoteError,
|
|
25
|
+
report
|
|
26
|
+
} from "./chunk-463H6B56.js";
|
|
27
|
+
import {
|
|
28
|
+
protocol
|
|
29
|
+
} from "./chunk-GNPFWISJ.js";
|
|
30
|
+
|
|
31
|
+
// src/core/hydrate.ts
|
|
32
|
+
function hydrateSlot(target, holder, options) {
|
|
33
|
+
const name = options.name ?? "";
|
|
34
|
+
let props = options.props ?? {};
|
|
35
|
+
let handle = null;
|
|
36
|
+
let inner = null;
|
|
37
|
+
let status = "loading";
|
|
38
|
+
let dead = false;
|
|
39
|
+
const setStatus = (s, e = null) => {
|
|
40
|
+
status = s;
|
|
41
|
+
options.onStatus?.(s, e);
|
|
42
|
+
};
|
|
43
|
+
const fallback = (next = {}) => {
|
|
44
|
+
handle?.unmount();
|
|
45
|
+
handle = null;
|
|
46
|
+
inner = hostSlot(target, {
|
|
47
|
+
...options,
|
|
48
|
+
...next,
|
|
49
|
+
props,
|
|
50
|
+
onStatus(s, e) {
|
|
51
|
+
if (s !== "loading") holder.remove();
|
|
52
|
+
if (s !== "loading" || !holder.isConnected) setStatus(s, e);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const initial = props;
|
|
57
|
+
hydrateRemote(holder, name, props, options).then(
|
|
58
|
+
(h) => {
|
|
59
|
+
if (dead) return h?.unmount();
|
|
60
|
+
if (!h) return fallback();
|
|
61
|
+
handle = h;
|
|
62
|
+
if (props !== initial) h.update?.(props);
|
|
63
|
+
setStatus("ready");
|
|
64
|
+
},
|
|
65
|
+
(e) => {
|
|
66
|
+
if (dead) return;
|
|
67
|
+
holder.remove();
|
|
68
|
+
setStatus("error", isRemoteError(e) ? e : new RemoteError("MOUNT_FAILED", name, String(e), e));
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
return {
|
|
72
|
+
update(next) {
|
|
73
|
+
props = next;
|
|
74
|
+
(inner ?? handle)?.update?.(next);
|
|
75
|
+
},
|
|
76
|
+
set(next) {
|
|
77
|
+
if (inner) return inner.set(next);
|
|
78
|
+
const changed = next.name !== void 0 && next.name !== name || "isolate" in next && next.isolate !== options.isolate;
|
|
79
|
+
if (changed) holder.remove(), fallback(next);
|
|
80
|
+
},
|
|
81
|
+
retry() {
|
|
82
|
+
if (inner) return inner.retry();
|
|
83
|
+
holder.remove();
|
|
84
|
+
fallback();
|
|
85
|
+
},
|
|
86
|
+
destroy() {
|
|
87
|
+
dead = true;
|
|
88
|
+
inner?.destroy();
|
|
89
|
+
handle?.unmount();
|
|
90
|
+
holder.remove();
|
|
91
|
+
},
|
|
92
|
+
get status() {
|
|
93
|
+
return inner?.status ?? status;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function hydrateRemote(holder, name, props, options) {
|
|
98
|
+
const p = protocol();
|
|
99
|
+
await p.pending();
|
|
100
|
+
const isolate = options.isolate ?? registered(name)?.isolate ?? p.settings().isolate;
|
|
101
|
+
if (isolate === "iframe") return null;
|
|
102
|
+
const { module: mod, ...resolved } = await load(name, isolate, options.priority);
|
|
103
|
+
const shadow = isolate === "shadow";
|
|
104
|
+
const el = [...(shadow ? holder.shadowRoot : holder)?.children ?? []].find((c) => c.hasAttribute("data-vitral-root"));
|
|
105
|
+
if (typeof mod.hydrate !== "function" || !el) return null;
|
|
106
|
+
const untrack = track(name, resolved);
|
|
107
|
+
ctxHooks.watch?.(name);
|
|
108
|
+
const label = resolved.name ?? name;
|
|
109
|
+
let t = performance.now();
|
|
110
|
+
const [release, portal = document.body, shadowRoot = null, registry = customElements] = await injectStyles(resolved, shadow && holder, () => el, options.styles);
|
|
111
|
+
if (shadowRoot?.adoptedStyleSheets.length) for (const s of shadowRoot.querySelectorAll("style[data-vitral-ssr]")) s.remove();
|
|
112
|
+
metric(name, "css", t);
|
|
113
|
+
t = performance.now();
|
|
114
|
+
const scoped = scopedEvents();
|
|
115
|
+
const on = (type) => (fn) => (el.addEventListener(type, fn), () => el.removeEventListener(type, fn));
|
|
116
|
+
const ctx = {
|
|
117
|
+
name: label,
|
|
118
|
+
baseUrl: new URL(".", resolved.entry).href,
|
|
119
|
+
events: scoped.bus,
|
|
120
|
+
shadowRoot,
|
|
121
|
+
portalContainer: portal,
|
|
122
|
+
customElements: registry,
|
|
123
|
+
reportError(e) {
|
|
124
|
+
const err = report(isRemoteError(e) ? e : new RemoteError("RENDER_FAILED", label, String(e?.message ?? e), e), resolved);
|
|
125
|
+
if (options.onError) options.onError(err);
|
|
126
|
+
else console.error(err);
|
|
127
|
+
},
|
|
128
|
+
navigate,
|
|
129
|
+
protocol: p.protocol,
|
|
130
|
+
onActivate: on("vitral:activate"),
|
|
131
|
+
onDeactivate: on("vitral:deactivate")
|
|
132
|
+
};
|
|
133
|
+
if (ctxHooks.shared) ctx.shared = ctxHooks.shared(name, scoped.track);
|
|
134
|
+
let mounted;
|
|
135
|
+
try {
|
|
136
|
+
mounted = await mod.hydrate(el, props, ctx);
|
|
137
|
+
metric(name, "mount", t);
|
|
138
|
+
} catch (e) {
|
|
139
|
+
untrack();
|
|
140
|
+
scoped.dispose();
|
|
141
|
+
release();
|
|
142
|
+
el.remove();
|
|
143
|
+
throw report(new RemoteError("MOUNT_FAILED", label, "erro ao hidratar", e), resolved);
|
|
144
|
+
}
|
|
145
|
+
let alive = true;
|
|
146
|
+
const current = {
|
|
147
|
+
update(next) {
|
|
148
|
+
if (alive) mounted.update?.(next);
|
|
149
|
+
},
|
|
150
|
+
unmount() {
|
|
151
|
+
if (!alive) return;
|
|
152
|
+
alive = false;
|
|
153
|
+
try {
|
|
154
|
+
mounted.unmount();
|
|
155
|
+
} finally {
|
|
156
|
+
untrack();
|
|
157
|
+
scoped.dispose();
|
|
158
|
+
release();
|
|
159
|
+
el.remove();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
return refreshable(current, name, props, (latest) => mountOnce(holder, name, latest, options));
|
|
164
|
+
}
|
|
165
|
+
export {
|
|
166
|
+
hydrateRemote,
|
|
167
|
+
hydrateSlot
|
|
168
|
+
};
|
package/dist/iframe.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import {
|
|
2
2
|
splitName
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C3QOBAUE.js";
|
|
4
4
|
import {
|
|
5
5
|
verifyIntegrity
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UYOPJ4XQ.js";
|
|
7
7
|
import {
|
|
8
8
|
events,
|
|
9
9
|
navigate,
|
|
10
10
|
setFrameMounter,
|
|
11
11
|
track
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KZBH5MPD.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveEntry
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
} from "./chunk-5JNV45BB.js";
|
|
16
|
+
import "./chunk-KU6HF2EW.js";
|
|
17
17
|
import {
|
|
18
18
|
fetchBytes,
|
|
19
19
|
withRetry,
|
|
20
20
|
withTimeout
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
22
22
|
import {
|
|
23
23
|
RemoteError,
|
|
24
24
|
report
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-463H6B56.js";
|
|
26
26
|
import {
|
|
27
27
|
protocol
|
|
28
28
|
} from "./chunk-GNPFWISJ.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { V as VitralConfig, c as RemoteEntry, P as Props, a as RemoteModule, I as Isolation,
|
|
2
|
-
export { C as CheckedProps, H as Handler,
|
|
1
|
+
import { V as VitralConfig, c as RemoteEntry, P as Props, a as RemoteModule, I as Isolation, d as StyleOptions, M as MountedRemote, E as EventBus, R as RemoteContext, e as SharedValue } from './types-DUtcF3HO.js';
|
|
2
|
+
export { f as Channel, g as ChannelContext, C as CheckedProps, D as DevOverrides, H as Handler, h as McpAppBridge, i as PropsOf, j as ProvideOptions, k as ProvidedValue, l as RemoteContract, m as RemoteManifest, n as RemoteMetric, o as Remotes, p as RollbackInfo, S as Shared, q as SharedApi, b as SharedModules, r as SharedType, s as batch, t as provide, u as shared } from './types-DUtcF3HO.js';
|
|
3
3
|
import { R as RemoteError } from './errors-kjBv6IH_.js';
|
|
4
4
|
export { a as RemoteErrorCode } from './errors-kjBv6IH_.js';
|
|
5
|
-
export { R as RemoteSlot, a as SlotOptions, S as SlotStatus, c as createSlot } from './slot-
|
|
6
|
-
export { e as events } from './events-
|
|
5
|
+
export { R as RemoteSlot, a as SlotOptions, S as SlotStatus, c as createSlot } from './slot-D49L1rdU.js';
|
|
6
|
+
export { e as events } from './events-0rxFlWJJ.js';
|
|
7
7
|
export { n as navigate } from './navigate-BRG1WJUM.js';
|
|
8
8
|
export { r as __reset } from './state-BDdCwc21.js';
|
|
9
9
|
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
syncTabs,
|
|
18
18
|
unsafeHTML,
|
|
19
19
|
watchUpdates
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-KZBH5MPD.js";
|
|
21
21
|
import {
|
|
22
22
|
configure,
|
|
23
23
|
loadModule,
|
|
@@ -25,12 +25,12 @@ import {
|
|
|
25
25
|
preload,
|
|
26
26
|
register,
|
|
27
27
|
registerSrc
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
28
|
+
} from "./chunk-5JNV45BB.js";
|
|
29
|
+
import "./chunk-KU6HF2EW.js";
|
|
30
|
+
import "./chunk-TW7KYJQ6.js";
|
|
31
31
|
import {
|
|
32
32
|
RemoteError
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-463H6B56.js";
|
|
34
34
|
import {
|
|
35
35
|
createEventBus,
|
|
36
36
|
resetProtocol
|
package/dist/otel.d.ts
CHANGED
|
@@ -40,5 +40,33 @@ interface OtelOptions {
|
|
|
40
40
|
}
|
|
41
41
|
/** `onError` para o `configure` que registra cada `RemoteError` no OpenTelemetry. */
|
|
42
42
|
declare function otelOnError({ trace, tracer }: OtelOptions): (error: RemoteError) => void;
|
|
43
|
+
/** A parte de um `Meter` de `@opentelemetry/api` que `otelVitals` usa. */
|
|
44
|
+
interface MeterLike {
|
|
45
|
+
createHistogram(name: string, options?: {
|
|
46
|
+
unit?: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
}): {
|
|
49
|
+
record(value: number, attributes?: Attributes): void;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* `onReport` para o `vitals()` de `vitral/vitals` que grava cada Web Vital
|
|
54
|
+
* num histograma `vitral.vitals.<lcp|cls|inp|fcp|ttfb>`:
|
|
55
|
+
*
|
|
56
|
+
* import { metrics } from '@opentelemetry/api'
|
|
57
|
+
* vitals({ onReport: otelVitals(metrics.getMeter('host')) })
|
|
58
|
+
*
|
|
59
|
+
* Atributos: `vitral.remote`, `vitral.version`, `vitral.route`,
|
|
60
|
+
* `vitral.navigation_id` e `vitral.rating`. Os ausentes ficam de fora.
|
|
61
|
+
*/
|
|
62
|
+
declare function otelVitals(meter: MeterLike): (report: {
|
|
63
|
+
name: string;
|
|
64
|
+
remote?: string;
|
|
65
|
+
version?: string;
|
|
66
|
+
route: string;
|
|
67
|
+
navigationId?: string;
|
|
68
|
+
value: number;
|
|
69
|
+
rating: string;
|
|
70
|
+
}) => void;
|
|
43
71
|
|
|
44
|
-
export { type Attributes, type OtelOptions, type SpanLike, otelOnError };
|
|
72
|
+
export { type Attributes, type MeterLike, type OtelOptions, type SpanLike, otelOnError, otelVitals };
|
package/dist/otel.js
CHANGED
|
@@ -22,6 +22,18 @@ function otelOnError({ trace, tracer }) {
|
|
|
22
22
|
span.end();
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
+
function otelVitals(meter) {
|
|
26
|
+
const histograms = {};
|
|
27
|
+
return (r) => {
|
|
28
|
+
const attributes = { "vitral.route": r.route, "vitral.rating": r.rating };
|
|
29
|
+
if (r.remote) attributes["vitral.remote"] = r.remote;
|
|
30
|
+
if (r.version) attributes["vitral.version"] = r.version;
|
|
31
|
+
if (r.navigationId) attributes["vitral.navigation_id"] = r.navigationId;
|
|
32
|
+
const name = r.name.toLowerCase();
|
|
33
|
+
(histograms[name] ??= meter.createHistogram("vitral.vitals." + name, { unit: name == "cls" ? "1" : "ms" })).record(r.value, attributes);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
25
36
|
export {
|
|
26
|
-
otelOnError
|
|
37
|
+
otelOnError,
|
|
38
|
+
otelVitals
|
|
27
39
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OVERRIDES_KEY,
|
|
3
|
+
activeOverrides,
|
|
4
|
+
clearOverrides,
|
|
5
|
+
dropOverride,
|
|
6
|
+
isRef,
|
|
7
|
+
manifestUrl,
|
|
8
|
+
overrideFor,
|
|
9
|
+
overridesEnabled,
|
|
10
|
+
resolveOverride,
|
|
11
|
+
storeOverride,
|
|
12
|
+
storedOverrides
|
|
13
|
+
} from "./chunk-54CBIZES.js";
|
|
14
|
+
import "./chunk-GNPFWISJ.js";
|
|
15
|
+
export {
|
|
16
|
+
OVERRIDES_KEY,
|
|
17
|
+
activeOverrides,
|
|
18
|
+
clearOverrides,
|
|
19
|
+
dropOverride,
|
|
20
|
+
isRef,
|
|
21
|
+
manifestUrl,
|
|
22
|
+
overrideFor,
|
|
23
|
+
overridesEnabled,
|
|
24
|
+
resolveOverride,
|
|
25
|
+
storeOverride,
|
|
26
|
+
storedOverrides
|
|
27
|
+
};
|
package/dist/preact.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as preact from 'preact';
|
|
2
2
|
import { VNode, ComponentType } from 'preact';
|
|
3
|
-
import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared } from './types-
|
|
4
|
-
export { R as RemoteContext } from './types-
|
|
3
|
+
import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared } from './types-DUtcF3HO.js';
|
|
4
|
+
export { R as RemoteContext } from './types-DUtcF3HO.js';
|
|
5
5
|
import { R as RemoteError } from './errors-kjBv6IH_.js';
|
|
6
|
-
import { S as SlotStatus } from './slot-
|
|
7
|
-
export { e as events } from './events-
|
|
6
|
+
import { S as SlotStatus } from './slot-D49L1rdU.js';
|
|
7
|
+
export { e as events } from './events-0rxFlWJJ.js';
|
|
8
8
|
export { n as navigate } from './navigate-BRG1WJUM.js';
|
|
9
9
|
import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
|
|
10
10
|
|
package/dist/preact.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hostSlot
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4Z77XNBR.js";
|
|
4
4
|
import {
|
|
5
5
|
defineRemote,
|
|
6
6
|
events,
|
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
navigate,
|
|
9
9
|
same,
|
|
10
10
|
shared
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-KZBH5MPD.js";
|
|
12
|
+
import "./chunk-5JNV45BB.js";
|
|
13
|
+
import "./chunk-KU6HF2EW.js";
|
|
14
|
+
import "./chunk-TW7KYJQ6.js";
|
|
15
|
+
import "./chunk-463H6B56.js";
|
|
16
16
|
import "./chunk-GNPFWISJ.js";
|
|
17
17
|
|
|
18
18
|
// src/preact.ts
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface PrefetchOptions {
|
|
2
|
+
/** Probabilidade mínima da rota seguinte para baixar os remotes dela. Padrão: 0.4. */
|
|
3
|
+
threshold?: number;
|
|
4
|
+
/** Transições contadas a partir da rota atual antes de prever. Padrão: 2. */
|
|
5
|
+
min?: number;
|
|
6
|
+
/** Onde guardar as contagens. `null` guarda só na memória. Padrão: localStorage. */
|
|
7
|
+
storage?: Pick<Storage, 'getItem' | 'setItem'> | null;
|
|
8
|
+
/** Chave da rota. Padrão: `url.pathname`. */
|
|
9
|
+
key?: (url: URL) => string;
|
|
10
|
+
/** Chamado depois de baixar os remotes previstos. */
|
|
11
|
+
onPrefetch?: (remotes: string[], route: string) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Começa a aprender as rotas e a pré-carregar o próximo remote. Devolve a
|
|
15
|
+
* função que para tudo (as contagens continuam guardadas).
|
|
16
|
+
*/
|
|
17
|
+
declare function prefetch(options?: PrefetchOptions): () => void;
|
|
18
|
+
/**
|
|
19
|
+
* Baixa o manifesto e os arquivos de um remote sem executar nada. Com
|
|
20
|
+
* integrity, pelo mesmo caminho de SRI que a montagem vai usar. Devolve
|
|
21
|
+
* false se o remote não pôde ser pré-carregado (sem erro no console).
|
|
22
|
+
*/
|
|
23
|
+
declare function warm(name: string): Promise<boolean>;
|
|
24
|
+
|
|
25
|
+
export { type PrefetchOptions, prefetch, warm };
|
package/dist/prefetch.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveEntry
|
|
3
|
+
} from "./chunk-5JNV45BB.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
|
+
};
|