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.
Files changed (70) hide show
  1. package/dist/angular.d.ts +2 -2
  2. package/dist/angular.js +7 -7
  3. package/dist/auto.js +7 -7
  4. package/dist/{capture-JYFERAPL.js → capture-TT5WBLJ6.js} +1 -1
  5. package/dist/channel-2YPYGX3J.js +95 -0
  6. package/dist/{chunk-AKNNHQ2H.js → chunk-463H6B56.js} +5 -0
  7. package/dist/{chunk-IHTUM6LT.js → chunk-4Z77XNBR.js} +2 -2
  8. package/dist/chunk-54CBIZES.js +105 -0
  9. package/dist/{chunk-TD4S3IHA.js → chunk-5JNV45BB.js} +10 -8
  10. package/dist/{chunk-SDB5AZEI.js → chunk-C3QOBAUE.js} +2 -2
  11. package/dist/chunk-DAESKNQ6.js +207 -0
  12. package/dist/{chunk-3YXI3G34.js → chunk-K6EG7DMO.js} +16 -7
  13. package/dist/{chunk-ZAC6QQI6.js → chunk-KU6HF2EW.js} +4 -4
  14. package/dist/{chunk-I3VSKSAZ.js → chunk-KZBH5MPD.js} +29 -27
  15. package/dist/chunk-NZEQGRBL.js +93 -0
  16. package/dist/chunk-PY7P5BF4.js +404 -0
  17. package/dist/{chunk-GNHCZRQP.js → chunk-TW7KYJQ6.js} +1 -1
  18. package/dist/{chunk-AH7KNMBW.js → chunk-UYOPJ4XQ.js} +1 -1
  19. package/dist/cli.js +1522 -37
  20. package/dist/devtools.d.ts +32 -2
  21. package/dist/devtools.js +27 -12
  22. package/dist/dict.d.ts +69 -0
  23. package/dist/dict.js +8 -0
  24. package/dist/edge.d.ts +118 -0
  25. package/dist/edge.js +398 -0
  26. package/dist/element.d.ts +12 -3
  27. package/dist/element.js +7 -7
  28. package/dist/embed.js +2 -0
  29. package/dist/{events-D5gs7rff.d.ts → events-0rxFlWJJ.d.ts} +1 -1
  30. package/dist/expose-IAKYHJXF.js +15 -0
  31. package/dist/federation.d.ts +89 -0
  32. package/dist/federation.js +101 -0
  33. package/dist/hydrate-YVZDJ2V7.js +168 -0
  34. package/dist/iframe.js +7 -7
  35. package/dist/index.d.ts +4 -4
  36. package/dist/index.js +5 -5
  37. package/dist/otel.d.ts +29 -1
  38. package/dist/otel.js +13 -1
  39. package/dist/overrides-NP754HY7.js +27 -0
  40. package/dist/preact.d.ts +4 -4
  41. package/dist/preact.js +6 -6
  42. package/dist/prefetch.d.ts +25 -0
  43. package/dist/prefetch.js +178 -0
  44. package/dist/react.d.ts +3 -3
  45. package/dist/react.js +6 -6
  46. package/dist/reframe-LQL4DZYP.js +251 -0
  47. package/dist/routes.d.ts +2 -2
  48. package/dist/routes.js +5 -5
  49. package/dist/{shadow-6HELCHCJ.js → shadow-S4SKHTA7.js} +66 -5
  50. package/dist/single-spa.d.ts +40 -0
  51. package/dist/single-spa.js +52 -0
  52. package/dist/{slot-DqXTwGbs.d.ts → slot-D49L1rdU.d.ts} +1 -1
  53. package/dist/solid.d.ts +3 -3
  54. package/dist/solid.js +6 -6
  55. package/dist/{sri-JMX6JLQP.js → sri-576GTDIA.js} +41 -10
  56. package/dist/svelte.d.ts +4 -4
  57. package/dist/svelte.js +6 -6
  58. package/dist/testing.d.ts +171 -3
  59. package/dist/testing.js +193 -6
  60. package/dist/{types-Czvm-siZ.d.ts → types-DUtcF3HO.d.ts} +124 -5
  61. package/dist/vitals.d.ts +29 -0
  62. package/dist/vitals.js +152 -0
  63. package/dist/vite.d.ts +18 -0
  64. package/dist/vite.js +329 -417
  65. package/dist/vue.d.ts +3 -3
  66. package/dist/vue.js +6 -6
  67. package/package.json +170 -21
  68. package/dist/chunk-DXORSF4X.js +0 -42
  69. package/dist/expose-JUOUN5N5.js +0 -15
  70. package/dist/overrides-NZAIUGK5.js +0 -15
package/dist/angular.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { InjectionToken, Type, ApplicationConfig, Signal, Provider, EnvironmentProviders } from '@angular/core';
2
- import { R as RemoteContext, P as Props, a as RemoteModule, S as Shared, V as VitralConfig } from './types-Czvm-siZ.js';
3
- export { e as events } from './events-D5gs7rff.js';
2
+ import { R as RemoteContext, P as Props, a as RemoteModule, S as Shared, V as VitralConfig } from './types-DUtcF3HO.js';
3
+ export { e as events } from './events-0rxFlWJJ.js';
4
4
  export { n as navigate } from './navigate-BRG1WJUM.js';
5
5
  import './errors-kjBv6IH_.js';
6
6
 
package/dist/angular.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  defineVitralElement
3
- } from "./chunk-3YXI3G34.js";
4
- import "./chunk-IHTUM6LT.js";
3
+ } from "./chunk-K6EG7DMO.js";
4
+ import "./chunk-4Z77XNBR.js";
5
5
  import {
6
6
  defineRemote,
7
7
  events,
@@ -9,13 +9,13 @@ import {
9
9
  navigate,
10
10
  same,
11
11
  shared
12
- } from "./chunk-I3VSKSAZ.js";
12
+ } from "./chunk-KZBH5MPD.js";
13
13
  import {
14
14
  configure
15
- } from "./chunk-TD4S3IHA.js";
16
- import "./chunk-ZAC6QQI6.js";
17
- import "./chunk-GNHCZRQP.js";
18
- import "./chunk-AKNNHQ2H.js";
15
+ } from "./chunk-5JNV45BB.js";
16
+ import "./chunk-KU6HF2EW.js";
17
+ import "./chunk-TW7KYJQ6.js";
18
+ import "./chunk-463H6B56.js";
19
19
  import "./chunk-GNPFWISJ.js";
20
20
 
21
21
  // src/angular.ts
package/dist/auto.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  defineVitralElement
3
- } from "./chunk-3YXI3G34.js";
4
- import "./chunk-IHTUM6LT.js";
5
- import "./chunk-I3VSKSAZ.js";
6
- import "./chunk-TD4S3IHA.js";
7
- import "./chunk-ZAC6QQI6.js";
8
- import "./chunk-GNHCZRQP.js";
9
- import "./chunk-AKNNHQ2H.js";
3
+ } from "./chunk-K6EG7DMO.js";
4
+ import "./chunk-4Z77XNBR.js";
5
+ import "./chunk-KZBH5MPD.js";
6
+ import "./chunk-5JNV45BB.js";
7
+ import "./chunk-KU6HF2EW.js";
8
+ import "./chunk-TW7KYJQ6.js";
9
+ import "./chunk-463H6B56.js";
10
10
  import "./chunk-GNPFWISJ.js";
11
11
 
12
12
  // src/auto.ts
@@ -4,7 +4,7 @@ import {
4
4
  mounted,
5
5
  report,
6
6
  reported
7
- } from "./chunk-AKNNHQ2H.js";
7
+ } from "./chunk-463H6B56.js";
8
8
  import {
9
9
  protocol
10
10
  } from "./chunk-GNPFWISJ.js";
@@ -0,0 +1,95 @@
1
+ import {
2
+ absolute
3
+ } from "./chunk-TW7KYJQ6.js";
4
+ import {
5
+ RemoteError,
6
+ ctxHooks
7
+ } from "./chunk-463H6B56.js";
8
+ import {
9
+ protocol
10
+ } from "./chunk-GNPFWISJ.js";
11
+
12
+ // src/core/channel.ts
13
+ var ROLLBACK_KEY = "vitral:rollback";
14
+ var ID_KEY = "vitral:id";
15
+ var watching = /* @__PURE__ */ new Map();
16
+ var abandoned = {};
17
+ var id;
18
+ async function pick(name, entry, channel) {
19
+ if (typeof channel.stable != "string") throw new RemoteError("INVALID_MODULE", name, `canal inv\xE1lido em ${entry.url}: falta "stable"`);
20
+ ctxHooks.watch = watch;
21
+ const ctx = { name, bucket: bucket(name) };
22
+ const { canary, stable } = channel;
23
+ let version = await entry.resolve?.(channel, ctx) ?? (canary && ctx.bucket < canary.percent ? canary.version : stable);
24
+ if (version !== stable && rolledBack()[name] === version) version = stable;
25
+ if (version === stable || entry.rollback === false) watching.delete(name);
26
+ else if (watching.get(name)?.from !== version) {
27
+ watching.set(name, { from: version, to: stable, errors: 0, mounts: 0, max: { errors: 3, mounts: 20, ...entry.rollback } });
28
+ }
29
+ return { ...entry, url: versionUrl(version, entry.url), integrity: void 0, manifest: void 0 };
30
+ }
31
+ var versionUrl = (version, channel) => absolute(/[/:]|\.(m?js|json)$/.test(version) ? version : `${version}/vitral.json`, channel);
32
+ function bucket(name) {
33
+ const key = protocol().settings().canaryKey ?? browserId();
34
+ let h = 2166136261;
35
+ for (const c of `${key}:${name}`) h = Math.imul(h ^ c.charCodeAt(0), 16777619);
36
+ return (h >>> 0) % 100;
37
+ }
38
+ function browserId() {
39
+ try {
40
+ id ??= localStorage.getItem(ID_KEY) ?? void 0;
41
+ } catch {
42
+ }
43
+ if (!id) {
44
+ id = Math.random().toString(36).slice(2);
45
+ try {
46
+ localStorage.setItem(ID_KEY, id);
47
+ } catch {
48
+ }
49
+ }
50
+ return id;
51
+ }
52
+ function rolledBack() {
53
+ try {
54
+ return { ...JSON.parse(sessionStorage.getItem(ROLLBACK_KEY) || "{}"), ...abandoned };
55
+ } catch {
56
+ return abandoned;
57
+ }
58
+ }
59
+ function watch(name, error) {
60
+ for (const [key, w] of watching) {
61
+ if (name !== key && !name.startsWith(key + "/")) continue;
62
+ if (!error) {
63
+ if (++w.mounts > w.max.mounts) w.mounts = 1, w.errors = 0;
64
+ } else if (++w.errors >= w.max.errors) {
65
+ rollback(key, w);
66
+ }
67
+ }
68
+ }
69
+ function rollback(name, w) {
70
+ watching.delete(name);
71
+ abandoned = { ...rolledBack(), [name]: w.from };
72
+ try {
73
+ sessionStorage.setItem(ROLLBACK_KEY, JSON.stringify(abandoned));
74
+ } catch {
75
+ }
76
+ console.warn(`[vitral] ${name}: ${w.errors} erros em ${w.mounts} montagens da vers\xE3o ${w.from}; voltando para ${w.to}`);
77
+ try {
78
+ protocol().settings().onRollback?.({ name, from: w.from, to: w.to, errors: w.errors, mounts: w.mounts });
79
+ } catch {
80
+ }
81
+ const p = protocol();
82
+ p.register(name, p.entry(name));
83
+ p.events.emit("vitral:refresh", name);
84
+ }
85
+ function resetChannels() {
86
+ watching.clear();
87
+ abandoned = {};
88
+ id = void 0;
89
+ }
90
+ export {
91
+ bucket,
92
+ pick,
93
+ resetChannels,
94
+ versionUrl
95
+ };
@@ -2,6 +2,9 @@ import {
2
2
  protocol
3
3
  } from "./chunk-GNPFWISJ.js";
4
4
 
5
+ // src/core/hooks.ts
6
+ var ctxHooks = {};
7
+
5
8
  // src/core/errors.ts
6
9
  var ERROR_DOCS = "https://joaogabriel15.github.io/vitral/erros/";
7
10
  var RemoteError = class extends Error {
@@ -28,6 +31,7 @@ function report(e, from) {
28
31
  protocol().settings().onError?.(e);
29
32
  } catch {
30
33
  }
34
+ ctxHooks.watch?.(e.remote, e);
31
35
  }
32
36
  return e;
33
37
  }
@@ -36,6 +40,7 @@ var fail = (e) => {
36
40
  };
37
41
 
38
42
  export {
43
+ ctxHooks,
39
44
  RemoteError,
40
45
  isRemoteError,
41
46
  mounted,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createSlot
3
- } from "./chunk-I3VSKSAZ.js";
3
+ } from "./chunk-KZBH5MPD.js";
4
4
  import {
5
5
  preload,
6
6
  registerSrc
7
- } from "./chunk-TD4S3IHA.js";
7
+ } from "./chunk-5JNV45BB.js";
8
8
 
9
9
  // src/core/host-slot.ts
10
10
  var noop = () => {
@@ -0,0 +1,105 @@
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
+ var isRef = (value) => /^[\w.-]+$/.test(value);
12
+ var read = (store) => {
13
+ try {
14
+ return JSON.parse(store().getItem(OVERRIDES_KEY) ?? "{}") ?? {};
15
+ } catch {
16
+ return {};
17
+ }
18
+ };
19
+ var write = (store, all) => {
20
+ try {
21
+ if (Object.keys(all).length) store().setItem(OVERRIDES_KEY, JSON.stringify(all));
22
+ else store().removeItem(OVERRIDES_KEY);
23
+ } catch {
24
+ }
25
+ };
26
+ var local = () => localStorage;
27
+ var session = () => sessionStorage;
28
+ var storedOverrides = () => read(local);
29
+ function storeOverride(name, value) {
30
+ const all = storedOverrides();
31
+ if (value) all[name] = isRef(value) ? value : manifestUrl(value);
32
+ else delete all[name];
33
+ write(local, all);
34
+ }
35
+ function tabOverrides() {
36
+ const all = read(session);
37
+ const pairs = new URLSearchParams(location.search).getAll("vitral").join(",").split(",");
38
+ if (!pairs.some(Boolean)) return all;
39
+ for (const pair of pairs) {
40
+ const at = pair.indexOf("@");
41
+ if (pair === "off") clearOverrides(), Object.keys(all).forEach((k) => delete all[k]);
42
+ else if (at > 0 && pair.slice(at + 1) === "off") delete all[pair.slice(0, at)];
43
+ else if (at > 0) all[pair.slice(0, at)] = pair.slice(at + 1);
44
+ }
45
+ write(session, all);
46
+ return all;
47
+ }
48
+ function clearOverrides() {
49
+ write(session, {});
50
+ write(local, {});
51
+ }
52
+ function dropOverride(name) {
53
+ for (const store of [session, local]) {
54
+ const all = read(store);
55
+ delete all[name];
56
+ write(store, all);
57
+ }
58
+ }
59
+ function resolveOverride(name, value) {
60
+ if (!isRef(value)) return new URL(manifestUrl(value), location.href).href;
61
+ const d = protocol().settings().devOverrides;
62
+ const preview = typeof d === "object" ? d.preview : void 0;
63
+ if (!preview) return;
64
+ const url = preview.replace(/\{name\}/g, encodeURIComponent(name)).replace(/\{ref\}/g, encodeURIComponent(value));
65
+ return new URL(manifestUrl(url), location.href).href;
66
+ }
67
+ function activeOverrides() {
68
+ const tab = tabOverrides();
69
+ const all = {};
70
+ for (const [source, map] of [["navegador", storedOverrides()], ["aba", tab]]) {
71
+ for (const [name, value] of Object.entries(map)) all[name] = { name, value, url: resolveOverride(name, value), source };
72
+ }
73
+ return Object.values(all);
74
+ }
75
+ var warned = /* @__PURE__ */ new Set();
76
+ function overrideFor(name) {
77
+ if (!overridesEnabled()) return;
78
+ const o = activeOverrides().find((o2) => o2.name === name);
79
+ if (!o) return;
80
+ const first = !warned.has(name) && warned.add(name);
81
+ if (!o.url) {
82
+ if (first) console.warn(`[vitral] override ${name}@${o.value} ignorado: falta configure({ devOverrides: { preview } })`);
83
+ return;
84
+ }
85
+ const p = protocol();
86
+ const trusted = p.settings().trusted ?? [];
87
+ const origin = new URL(o.url).origin;
88
+ if (!trusted.includes(origin)) p.configure({ trusted: [...trusted, origin] });
89
+ if (first) console.warn(`[vitral] override ativo: ${name} \u2192 ${o.url} (${o.source}). Para limpar: ?vitral=off`);
90
+ return { url: o.url };
91
+ }
92
+
93
+ export {
94
+ OVERRIDES_KEY,
95
+ overridesEnabled,
96
+ manifestUrl,
97
+ isRef,
98
+ storedOverrides,
99
+ storeOverride,
100
+ clearOverrides,
101
+ dropOverride,
102
+ resolveOverride,
103
+ activeOverrides,
104
+ overrideFor
105
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  prefetchCss
3
- } from "./chunk-ZAC6QQI6.js";
3
+ } from "./chunk-KU6HF2EW.js";
4
4
  import {
5
5
  absolute,
6
6
  addLink,
@@ -9,13 +9,13 @@ import {
9
9
  pageOrigin,
10
10
  withRetry,
11
11
  withTimeout
12
- } from "./chunk-GNHCZRQP.js";
12
+ } from "./chunk-TW7KYJQ6.js";
13
13
  import {
14
14
  RemoteError,
15
15
  fail,
16
16
  isRemoteError,
17
17
  report
18
- } from "./chunk-AKNNHQ2H.js";
18
+ } from "./chunk-463H6B56.js";
19
19
  import {
20
20
  protocol
21
21
  } from "./chunk-GNPFWISJ.js";
@@ -25,7 +25,7 @@ function configure(config) {
25
25
  const p = protocol();
26
26
  const { remotes, dedupe, ...rest } = config;
27
27
  p.configure(rest);
28
- if (rest.captureGlobalErrors) import("./capture-JYFERAPL.js").then((m) => m.capture());
28
+ if (rest.captureGlobalErrors) import("./capture-TT5WBLJ6.js").then((m) => m.capture());
29
29
  if (dedupe) p.pending(import("./dedupe-S7BHQMOZ.js").then((m) => m.offer(p, dedupe)).catch(() => {
30
30
  }));
31
31
  if (typeof remotes === "string") {
@@ -79,7 +79,7 @@ function loadRemote(name) {
79
79
  return load(name).then((r) => r.module);
80
80
  }
81
81
  function loadModule(name) {
82
- return import("./expose-JUOUN5N5.js").then((m) => m.resolveModule(name, (n) => loadFile(n))).catch(fail);
82
+ return import("./expose-IAKYHJXF.js").then((m) => m.resolveModule(name, (n) => loadFile(n))).catch(fail);
83
83
  }
84
84
  function preload(name) {
85
85
  load(name).catch(() => {
@@ -88,12 +88,12 @@ function preload(name) {
88
88
  var paths;
89
89
  function load(name, isolate, priority) {
90
90
  const file = (n) => loadFile(n, isolate, priority);
91
- return (protocol().entry(name) || !name.includes("/") ? file(name).then((r) => mountable(name, r)) : import("./expose-JUOUN5N5.js").then((m) => m.resolveTarget(name, file))).catch(fail);
91
+ return (protocol().entry(name) || !name.includes("/") ? file(name).then((r) => mountable(name, r)) : import("./expose-IAKYHJXF.js").then((m) => m.resolveTarget(name, file))).catch(fail);
92
92
  }
93
93
  function loadFile(name, isolate, priority) {
94
94
  const p = protocol();
95
95
  return p.load(name, async () => {
96
- paths ??= import("./sri-JMX6JLQP.js").catch(() => null);
96
+ paths ??= import("./sri-576GTDIA.js").catch(() => null);
97
97
  let resolved;
98
98
  try {
99
99
  await p.pending();
@@ -116,7 +116,8 @@ function loadFile(name, isolate, priority) {
116
116
  }
117
117
  function devOverride(name) {
118
118
  try {
119
- if (/vitral/.test(location.search + localStorage.getItem("vitral:overrides"))) return import("./overrides-NZAIUGK5.js").then((m) => m.overrideFor(name));
119
+ const k = "vitral:overrides";
120
+ if (location.search.includes("vitral") || localStorage[k] || sessionStorage[k]) return import("./overrides-NP754HY7.js").then((m) => m.overrideFor(name));
120
121
  } catch {
121
122
  }
122
123
  }
@@ -128,6 +129,7 @@ async function loadLocal(name, entry) {
128
129
  async function resolveEntry(name, entry, priority) {
129
130
  checkOrigin(name, entry.url);
130
131
  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 });
132
+ if (m?.stable) return resolveEntry(name, await (await import("./channel-2YPYGX3J.js")).pick(name, entry, m), priority);
131
133
  if (typeof m?.entry !== "string") throw new RemoteError("INVALID_MODULE", name, `manifesto inv\xE1lido em ${entry.url}`);
132
134
  if (m.contract && (entry.contract || protocol().settings().contract)) {
133
135
  const why = await (await import("./contract-46EZFQPQ.js")).checkContract(m.contract, entry.contract);
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  mountable
3
- } from "./chunk-TD4S3IHA.js";
3
+ } from "./chunk-5JNV45BB.js";
4
4
  import {
5
5
  RemoteError
6
- } from "./chunk-AKNNHQ2H.js";
6
+ } from "./chunk-463H6B56.js";
7
7
  import {
8
8
  protocol
9
9
  } from "./chunk-GNPFWISJ.js";
@@ -0,0 +1,207 @@
1
+ // src/harness.ts
2
+ var CONTRACT_SCHEMA = "https://joaogabriel15.github.io/vitral/schema/vitral-contract.json";
3
+ function encode(value, seen = /* @__PURE__ */ new Set()) {
4
+ if (typeof value === "function") return { $fn: true };
5
+ if (value === void 0 || value === null || typeof value !== "object") {
6
+ return typeof value === "bigint" || typeof value === "symbol" ? { $unknown: typeof value } : value;
7
+ }
8
+ if (value instanceof Date) return { $date: value.toISOString() };
9
+ if (seen.has(value)) return { $unknown: "circular" };
10
+ const proto = Object.getPrototypeOf(value);
11
+ if (!Array.isArray(value) && proto !== Object.prototype && proto !== null) return { $unknown: proto?.constructor?.name ?? "Object" };
12
+ seen.add(value);
13
+ try {
14
+ if (Array.isArray(value)) return value.map((v) => encode(v, seen) ?? null);
15
+ const out = {};
16
+ for (const [k, v] of Object.entries(value)) if (v !== void 0) out[k] = encode(v, seen);
17
+ return out;
18
+ } finally {
19
+ seen.delete(value);
20
+ }
21
+ }
22
+ function decode(value, fn = () => () => void 0, path = "") {
23
+ if (!value || typeof value !== "object") return value;
24
+ if (Array.isArray(value)) return value.map((v2, i) => decode(v2, fn, `${path}[${i}]`));
25
+ const v = value;
26
+ if (v.$fn === true) return fn(path);
27
+ if (typeof v.$date === "string") return new Date(v.$date);
28
+ if (typeof v.$unknown === "string") return void 0;
29
+ return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, decode(x, fn, path ? `${path}.${k}` : k)]));
30
+ }
31
+ async function harness(mod, options) {
32
+ const remote = typeof mod.mount === "function" ? mod : mod.default;
33
+ if (typeof remote?.mount !== "function") throw new Error("[vitral] o m\xF3dulo n\xE3o exporta mount()");
34
+ const name = options.name ?? "remote";
35
+ const target = options.target ?? document.body.appendChild(document.createElement("div"));
36
+ const shadowRoot = options.shadow ? target.attachShadow({ mode: "open" }) : null;
37
+ const el = document.createElement("div");
38
+ el.setAttribute("data-vitral-root", name);
39
+ (shadowRoot ?? target).appendChild(el);
40
+ const portal = shadowRoot ? shadowRoot.appendChild(document.createElement("div")) : document.body;
41
+ const errors = [];
42
+ const emitted = [];
43
+ const navigations = [];
44
+ const handlers = /* @__PURE__ */ new Map();
45
+ const last = new Map(Object.entries(options.last ?? {}));
46
+ const dispatch = (type, payload) => {
47
+ last.set(type, payload);
48
+ for (const h of [...handlers.get(type) ?? []]) {
49
+ try {
50
+ h(payload);
51
+ } catch (e) {
52
+ errors.push(e);
53
+ }
54
+ }
55
+ };
56
+ const events = {
57
+ emit(type, payload) {
58
+ emitted.push({ type, payload });
59
+ dispatch(type, payload);
60
+ },
61
+ on(type, handler) {
62
+ let set = handlers.get(type);
63
+ if (!set) handlers.set(type, set = /* @__PURE__ */ new Set());
64
+ set.add(handler);
65
+ return () => set.delete(handler);
66
+ },
67
+ last: (type) => last.get(type)
68
+ };
69
+ const activate = /* @__PURE__ */ new Set();
70
+ const deactivate = /* @__PURE__ */ new Set();
71
+ const hook = (set) => (fn) => (set.add(fn), () => set.delete(fn));
72
+ const ctx = {
73
+ name,
74
+ baseUrl: typeof location !== "undefined" ? new URL(".", location.href).href : "http://localhost/",
75
+ events,
76
+ shadowRoot,
77
+ portalContainer: portal,
78
+ customElements,
79
+ reportError: (e) => errors.push(e),
80
+ navigate: (url, opts) => navigations.push({ url, options: opts }),
81
+ protocol: 1,
82
+ onActivate: hook(activate),
83
+ onDeactivate: hook(deactivate),
84
+ shared: memoryShared(options.shared ?? {}),
85
+ ...options.ctx
86
+ };
87
+ const mounted = await remote.mount(el, options.props, ctx);
88
+ let alive = true;
89
+ return {
90
+ el,
91
+ ctx,
92
+ events: emitted,
93
+ errors,
94
+ navigations,
95
+ listens: () => [...handlers].filter(([, s]) => s.size).map(([t]) => t),
96
+ emit: dispatch,
97
+ update(props) {
98
+ if (alive) mounted.update?.(props);
99
+ },
100
+ activate: () => activate.forEach((f) => f()),
101
+ deactivate: () => deactivate.forEach((f) => f()),
102
+ unmount() {
103
+ if (!alive) return;
104
+ alive = false;
105
+ try {
106
+ mounted.unmount();
107
+ } finally {
108
+ el.remove();
109
+ if (!options.target) target.remove();
110
+ }
111
+ }
112
+ };
113
+ }
114
+ function memoryShared(initial) {
115
+ const values = new Map(Object.entries(initial));
116
+ const subs = /* @__PURE__ */ new Map();
117
+ const handle = (key) => {
118
+ const set = (v) => {
119
+ values.set(key, v);
120
+ for (const fn of [...subs.get(key) ?? []]) fn(v);
121
+ };
122
+ return {
123
+ key,
124
+ get: () => values.get(key),
125
+ set,
126
+ update: (fn) => set(fn(values.get(key))),
127
+ subscribe(fn) {
128
+ fn(values.get(key));
129
+ let s = subs.get(key);
130
+ if (!s) subs.set(key, s = /* @__PURE__ */ new Set());
131
+ s.add(fn);
132
+ return () => s.delete(fn);
133
+ }
134
+ };
135
+ };
136
+ const api = handle;
137
+ api.provide = ((key, value) => {
138
+ if (!values.has(key)) values.set(key, value);
139
+ return handle(key);
140
+ });
141
+ api.batch = (fn) => fn();
142
+ return api;
143
+ }
144
+ var message = (e) => String(e?.message ?? e);
145
+ async function verify(contract, mod, options = {}) {
146
+ const failures = [];
147
+ const warnings = [];
148
+ const pause = () => new Promise((r) => setTimeout(r, options.wait ?? 0));
149
+ const cases = contract.cases ?? [];
150
+ for (const [i, c] of cases.entries()) {
151
+ const at = `caso ${i + 1}`;
152
+ const fail = (msg) => failures.push(`${at}: ${msg}`);
153
+ let h;
154
+ try {
155
+ h = await harness(mod, {
156
+ name: contract.remote,
157
+ props: decode(c.props),
158
+ shared: decode(c.shared ?? {}),
159
+ last: decode(c.last ?? {})
160
+ });
161
+ } catch (e) {
162
+ fail(`erro no mount: ${message(e)}`);
163
+ continue;
164
+ }
165
+ await pause();
166
+ for (const [j, u] of (c.updates ?? []).entries()) {
167
+ try {
168
+ h.update(decode(u));
169
+ } catch (e) {
170
+ fail(`erro no update ${j + 1}: ${message(e)}`);
171
+ }
172
+ }
173
+ if (c.updates?.length) await pause();
174
+ const deaf = /* @__PURE__ */ new Set();
175
+ for (const input of c.inputs ?? []) {
176
+ if (!h.listens().includes(input.type)) {
177
+ if (!deaf.has(input.type)) warnings.push(`${at}: o host emite "${input.type}" e o remote n\xE3o escuta mais`);
178
+ deaf.add(input.type);
179
+ continue;
180
+ }
181
+ h.emit(input.type, decode(input.payload));
182
+ }
183
+ await pause();
184
+ const seen = new Set(h.events.map((e) => e.type));
185
+ for (const e of c.emits ?? []) {
186
+ if (seen.has(e.type)) continue;
187
+ if (e.phase !== "later") fail(`o host escuta "${e.type}" e o remote n\xE3o emitiu (na grava\xE7\xE3o saiu no ${e.phase})`);
188
+ else if (!options.sources) warnings.push(`${at}: "${e.type}" sai depois do mount; sem o c\xF3digo do remote, n\xE3o deu para conferir`);
189
+ else if (!options.sources.some((s) => s.includes(e.type))) fail(`o host escuta "${e.type}" e o c\xF3digo do remote n\xE3o tem mais esse evento`);
190
+ }
191
+ try {
192
+ h.unmount();
193
+ } catch (e) {
194
+ fail(`erro no unmount: ${message(e)}`);
195
+ }
196
+ for (const e of h.errors) fail(`erro reportado: ${message(e)}`);
197
+ }
198
+ if (!cases.length) warnings.push("contrato sem casos");
199
+ return { cases: cases.length, failures, warnings };
200
+ }
201
+
202
+ export {
203
+ CONTRACT_SCHEMA,
204
+ encode,
205
+ harness,
206
+ verify
207
+ };
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  hostSlot,
3
3
  timings
4
- } from "./chunk-IHTUM6LT.js";
4
+ } from "./chunk-4Z77XNBR.js";
5
5
  import {
6
6
  defineRemote,
7
7
  memoSelect,
8
8
  same,
9
9
  shared
10
- } from "./chunk-I3VSKSAZ.js";
10
+ } from "./chunk-KZBH5MPD.js";
11
11
  import {
12
12
  registerSrc
13
- } from "./chunk-TD4S3IHA.js";
13
+ } from "./chunk-5JNV45BB.js";
14
14
 
15
15
  // src/element.ts
16
16
  var Base = typeof HTMLElement === "undefined" ? class {
@@ -40,7 +40,7 @@ var VitralRemoteElement = class extends Base {
40
40
  if (!name) return;
41
41
  if (this.hasAttribute("props") && !Object.keys(this.#props).length) this.#props = parseProps(this.getAttribute("props"));
42
42
  const keep = this.getAttribute("keep-alive");
43
- this.#slot = hostSlot(this, {
43
+ const options = {
44
44
  name,
45
45
  props: this.#props,
46
46
  isolate: this.getAttribute("isolate") || void 0,
@@ -66,7 +66,10 @@ var VitralRemoteElement = class extends Base {
66
66
  if (status === "ready") this.dispatchEvent(new CustomEvent("vitral-ready", { bubbles: true, detail: { timings: timings(name) } }));
67
67
  if (status === "error") this.dispatchEvent(new CustomEvent("vitral-error", { bubbles: true, detail: { error } }));
68
68
  }
69
- });
69
+ };
70
+ const ssr = true ? this.querySelector(":scope>[data-vitral-ssr]") : null;
71
+ if (ssr) import("./hydrate-YVZDJ2V7.js").then((m) => this.isConnected && !this.#slot && (this.#slot = m.hydrateSlot(this, ssr, { ...options, props: this.#props })));
72
+ else this.#slot = hostSlot(this, options);
70
73
  }
71
74
  /**
72
75
  * Nome para montar. `src` em atributo é registrado sem entrar na allowlist:
@@ -135,8 +138,14 @@ function defineVitralElement(tag = "vitral-remote") {
135
138
  function elementRemote(tag, setup) {
136
139
  return defineRemote({
137
140
  mount(el, props, ctx) {
138
- setup?.();
139
- const node = document.createElement(tag);
141
+ const registry = ctx.customElements ?? customElements;
142
+ const name = setup?.(registry) || tag;
143
+ let node;
144
+ try {
145
+ node = document.createElement(name, { customElementRegistry: registry });
146
+ } catch {
147
+ node = document.createElement(name);
148
+ }
140
149
  node.vitral = ctx;
141
150
  Object.assign(node, props);
142
151
  el.appendChild(node);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  addLink,
3
3
  fetchBytes
4
- } from "./chunk-GNHCZRQP.js";
4
+ } from "./chunk-TW7KYJQ6.js";
5
5
  import {
6
6
  protocol
7
7
  } from "./chunk-GNPFWISJ.js";
@@ -23,11 +23,11 @@ function fetchCssText(href, integrity, priority) {
23
23
  return p;
24
24
  }
25
25
  function prefetchCss(r, shadow, priority = "auto") {
26
- if (shadow && adopts()) import("./shadow-6HELCHCJ.js").then((m) => m.prefetch(r, priority), noop);
26
+ if (shadow && adopts()) import("./shadow-S4SKHTA7.js").then((m) => m.prefetch(r, priority), noop);
27
27
  else for (const href of r.css) if (!document.querySelector(`link[href="${href}"]`)) addLink("preload", href, { as: "style", integrity: r.sri?.[href] ?? "", fetchPriority: priority });
28
28
  }
29
- function injectStyles(r, root, el, styles) {
30
- return root ? import("./shadow-6HELCHCJ.js").then((m) => m.attachStyles(root, el, r, protocol().settings().styles, styles)) : injectCss(r.css, null, r.sri).then(() => [noop]);
29
+ function injectStyles(r, shadow, make, styles) {
30
+ return shadow ? import("./shadow-S4SKHTA7.js").then((m) => m.attachShadowRoot(shadow, make, r, protocol().settings().styles, styles)) : injectCss(r.css, null, r.sri).then(() => [noop]);
31
31
  }
32
32
  function injectCss(urls, root, sri = {}) {
33
33
  const owner = root ?? document;