vitral 0.5.0 → 0.7.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 (48) hide show
  1. package/dist/angular.d.ts +2 -2
  2. package/dist/angular.js +4 -4
  3. package/dist/auto.js +4 -4
  4. package/dist/{chunk-C3QOBAUE.js → chunk-4NSPG6NK.js} +1 -1
  5. package/dist/{chunk-5JNV45BB.js → chunk-72H4FXMD.js} +22 -5
  6. package/dist/chunk-B2MPYF4M.js +27 -0
  7. package/dist/{chunk-KZBH5MPD.js → chunk-O7DV3EVB.js} +4 -4
  8. package/dist/chunk-OVVGVPIV.js +21 -0
  9. package/dist/{chunk-4Z77XNBR.js → chunk-TXSHK3SK.js} +2 -2
  10. package/dist/{chunk-K6EG7DMO.js → chunk-V24ZNHUF.js} +6 -5
  11. package/dist/edge.d.ts +9 -3
  12. package/dist/edge.js +25 -10
  13. package/dist/element.d.ts +2 -2
  14. package/dist/element.js +4 -4
  15. package/dist/embed.js +2 -2
  16. package/dist/{events-0rxFlWJJ.d.ts → events-DLdbFqBM.d.ts} +1 -1
  17. package/dist/{expose-IAKYHJXF.js → expose-ZLYQZUP2.js} +2 -2
  18. package/dist/federation.d.ts +1 -1
  19. package/dist/{hydrate-YVZDJ2V7.js → hydrate-NFZZMYWT.js} +18 -4
  20. package/dist/iframe.js +3 -3
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.js +2 -2
  23. package/dist/match-CMBM_jLW.d.ts +16 -0
  24. package/dist/preact.d.ts +4 -4
  25. package/dist/preact.js +3 -3
  26. package/dist/prefetch.js +1 -1
  27. package/dist/react-server.d.ts +20 -0
  28. package/dist/react-server.js +13 -0
  29. package/dist/react.d.ts +7 -4
  30. package/dist/react.js +18 -30
  31. package/dist/{reframe-LQL4DZYP.js → reframe-7K5S6JC6.js} +2 -2
  32. package/dist/routes.d.ts +4 -13
  33. package/dist/routes.js +26 -22
  34. package/dist/single-spa.d.ts +1 -1
  35. package/dist/{slot-D49L1rdU.d.ts → slot-Ddzp7AgL.d.ts} +1 -1
  36. package/dist/solid.d.ts +3 -3
  37. package/dist/solid.js +3 -3
  38. package/dist/stale-HFTCJASS.js +15 -0
  39. package/dist/svelte.d.ts +4 -4
  40. package/dist/svelte.js +3 -3
  41. package/dist/testing.d.ts +1 -1
  42. package/dist/testing.js +2 -2
  43. package/dist/{types-DUtcF3HO.d.ts → types-EOz1rOHs.d.ts} +8 -0
  44. package/dist/vite.d.ts +7 -0
  45. package/dist/vite.js +6 -4
  46. package/dist/vue.d.ts +2 -2
  47. package/dist/vue.js +3 -3
  48. package/package.json +22 -7
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hostSlot
3
- } from "./chunk-4Z77XNBR.js";
3
+ } from "./chunk-TXSHK3SK.js";
4
4
  import {
5
5
  mountOnce,
6
6
  navigate,
@@ -8,14 +8,15 @@ import {
8
8
  registered,
9
9
  scopedEvents,
10
10
  track
11
- } from "./chunk-KZBH5MPD.js";
11
+ } from "./chunk-O7DV3EVB.js";
12
12
  import {
13
13
  load
14
- } from "./chunk-5JNV45BB.js";
14
+ } from "./chunk-72H4FXMD.js";
15
15
  import {
16
16
  injectStyles
17
17
  } from "./chunk-KU6HF2EW.js";
18
18
  import {
19
+ absolute,
19
20
  metric
20
21
  } from "./chunk-TW7KYJQ6.js";
21
22
  import {
@@ -99,7 +100,10 @@ async function hydrateRemote(holder, name, props, options) {
99
100
  await p.pending();
100
101
  const isolate = options.isolate ?? registered(name)?.isolate ?? p.settings().isolate;
101
102
  if (isolate === "iframe") return null;
102
- const { module: mod, ...resolved } = await load(name, isolate, options.priority);
103
+ const entry = p.entry(name);
104
+ const seed = entry?.url && !entry.manifest ? manifestFrom(holder, entry.url) : void 0;
105
+ if (seed) entry.manifest = seed;
106
+ const { module: mod, ...resolved } = await load(name, isolate, options.priority).finally(() => seed && entry.manifest === seed && delete entry.manifest);
103
107
  const shadow = isolate === "shadow";
104
108
  const el = [...(shadow ? holder.shadowRoot : holder)?.children ?? []].find((c) => c.hasAttribute("data-vitral-root"));
105
109
  if (typeof mod.hydrate !== "function" || !el) return null;
@@ -162,6 +166,16 @@ async function hydrateRemote(holder, name, props, options) {
162
166
  };
163
167
  return refreshable(current, name, props, (latest) => mountOnce(holder, name, latest, options));
164
168
  }
169
+ function manifestFrom(holder, url) {
170
+ for (const s of holder.querySelectorAll(":scope>script[data-vitral-manifest]")) {
171
+ if (absolute(s.getAttribute("data-vitral-manifest") ?? "") !== url) continue;
172
+ try {
173
+ const m = JSON.parse(s.textContent ?? "");
174
+ if (typeof m?.entry === "string") return m;
175
+ } catch {
176
+ }
177
+ }
178
+ }
165
179
  export {
166
180
  hydrateRemote,
167
181
  hydrateSlot
package/dist/iframe.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  splitName
3
- } from "./chunk-C3QOBAUE.js";
3
+ } from "./chunk-4NSPG6NK.js";
4
4
  import {
5
5
  verifyIntegrity
6
6
  } from "./chunk-UYOPJ4XQ.js";
@@ -9,10 +9,10 @@ import {
9
9
  navigate,
10
10
  setFrameMounter,
11
11
  track
12
- } from "./chunk-KZBH5MPD.js";
12
+ } from "./chunk-O7DV3EVB.js";
13
13
  import {
14
14
  resolveEntry
15
- } from "./chunk-5JNV45BB.js";
15
+ } from "./chunk-72H4FXMD.js";
16
16
  import "./chunk-KU6HF2EW.js";
17
17
  import {
18
18
  fetchBytes,
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, 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';
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-EOz1rOHs.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-EOz1rOHs.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-D49L1rdU.js';
6
- export { e as events } from './events-0rxFlWJJ.js';
5
+ export { R as RemoteSlot, a as SlotOptions, S as SlotStatus, c as createSlot } from './slot-Ddzp7AgL.js';
6
+ export { e as events } from './events-DLdbFqBM.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-KZBH5MPD.js";
20
+ } from "./chunk-O7DV3EVB.js";
21
21
  import {
22
22
  configure,
23
23
  loadModule,
@@ -25,7 +25,7 @@ import {
25
25
  preload,
26
26
  register,
27
27
  registerSrc
28
- } from "./chunk-5JNV45BB.js";
28
+ } from "./chunk-72H4FXMD.js";
29
29
  import "./chunk-KU6HF2EW.js";
30
30
  import "./chunk-TW7KYJQ6.js";
31
31
  import {
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Rotas → remote, sem DOM: o `<vitral-outlet>` (`vitral/routes`) e o gateway
3
+ * (`vitral/edge`) usam o mesmo mapa e a mesma regra.
4
+ */
5
+ /** Padrão de URL → nome do remote. A primeira rota que bate vence. */
6
+ type Routes = Record<string, string>;
7
+ interface RouteMatch {
8
+ /** Nome do remote. */
9
+ name: string;
10
+ /** Padrão que bateu. */
11
+ pattern: string;
12
+ /** Segmentos `:nome` do padrão. */
13
+ params: Record<string, string>;
14
+ }
15
+
16
+ export type { Routes as R, RouteMatch as a };
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-DUtcF3HO.js';
4
- export { R as RemoteContext } from './types-DUtcF3HO.js';
3
+ import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared } from './types-EOz1rOHs.js';
4
+ export { R as RemoteContext } from './types-EOz1rOHs.js';
5
5
  import { R as RemoteError } from './errors-kjBv6IH_.js';
6
- import { S as SlotStatus } from './slot-D49L1rdU.js';
7
- export { e as events } from './events-0rxFlWJJ.js';
6
+ import { S as SlotStatus } from './slot-Ddzp7AgL.js';
7
+ export { e as events } from './events-DLdbFqBM.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-4Z77XNBR.js";
3
+ } from "./chunk-TXSHK3SK.js";
4
4
  import {
5
5
  defineRemote,
6
6
  events,
@@ -8,8 +8,8 @@ import {
8
8
  navigate,
9
9
  same,
10
10
  shared
11
- } from "./chunk-KZBH5MPD.js";
12
- import "./chunk-5JNV45BB.js";
11
+ } from "./chunk-O7DV3EVB.js";
12
+ import "./chunk-72H4FXMD.js";
13
13
  import "./chunk-KU6HF2EW.js";
14
14
  import "./chunk-TW7KYJQ6.js";
15
15
  import "./chunk-463H6B56.js";
package/dist/prefetch.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveEntry
3
- } from "./chunk-5JNV45BB.js";
3
+ } from "./chunk-72H4FXMD.js";
4
4
  import "./chunk-KU6HF2EW.js";
5
5
  import {
6
6
  addLink
@@ -0,0 +1,20 @@
1
+ import { ComponentType } from 'react';
2
+ import { P as Props } from './types-EOz1rOHs.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-DUtcF3HO.js';
5
- export { E as EventBus } from './types-DUtcF3HO.js';
6
- export { e as events } from './events-0rxFlWJJ.js';
4
+ import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared, R as RemoteContext } from './types-EOz1rOHs.js';
5
+ export { E as EventBus } from './types-EOz1rOHs.js';
6
+ export { e as events } from './events-DLdbFqBM.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
- /** Transforma um componente React em um remote. */
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,15 +1,19 @@
1
1
  "use client";
2
+ import {
3
+ RemoteTree,
4
+ VitralContext
5
+ } from "./chunk-B2MPYF4M.js";
2
6
  import {
3
7
  hostSlot
4
- } from "./chunk-4Z77XNBR.js";
8
+ } from "./chunk-TXSHK3SK.js";
5
9
  import {
6
10
  defineRemote,
7
11
  events,
8
12
  memoSelect,
9
13
  same,
10
14
  shared
11
- } from "./chunk-KZBH5MPD.js";
12
- import "./chunk-5JNV45BB.js";
15
+ } from "./chunk-O7DV3EVB.js";
16
+ import "./chunk-72H4FXMD.js";
13
17
  import "./chunk-KU6HF2EW.js";
14
18
  import "./chunk-TW7KYJQ6.js";
15
19
  import "./chunk-463H6B56.js";
@@ -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
- const root = createRoot(el, { onUncaughtError: (e) => ctx.reportError(e) });
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() {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  splitName
3
- } from "./chunk-C3QOBAUE.js";
3
+ } from "./chunk-4NSPG6NK.js";
4
4
  import {
5
5
  verifyIntegrity
6
6
  } from "./chunk-UYOPJ4XQ.js";
7
7
  import {
8
8
  resolveEntry
9
- } from "./chunk-5JNV45BB.js";
9
+ } from "./chunk-72H4FXMD.js";
10
10
  import {
11
11
  prefetchCss
12
12
  } from "./chunk-KU6HF2EW.js";
package/dist/routes.d.ts CHANGED
@@ -1,9 +1,8 @@
1
- import { P as Props } from './types-DUtcF3HO.js';
2
- import { S as SlotStatus } from './slot-D49L1rdU.js';
1
+ import { R as Routes, a as RouteMatch } from './match-CMBM_jLW.js';
2
+ import { P as Props } from './types-EOz1rOHs.js';
3
+ import { S as SlotStatus } from './slot-Ddzp7AgL.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 { type RouteMatch, type Routes, type RoutesOptions, VitralOutletElement, defineVitralOutlet, matchRoute, routes };
47
+ export { RouteMatch, Routes, type RoutesOptions, VitralOutletElement, defineVitralOutlet, matchRoute, routes };
package/dist/routes.js CHANGED
@@ -1,8 +1,13 @@
1
+ import {
2
+ matchRoute
3
+ } from "./chunk-OVVGVPIV.js";
1
4
  import {
2
5
  createSlot,
3
6
  navigate
4
- } from "./chunk-KZBH5MPD.js";
5
- import "./chunk-5JNV45BB.js";
7
+ } from "./chunk-O7DV3EVB.js";
8
+ import {
9
+ warmSsr
10
+ } from "./chunk-72H4FXMD.js";
6
11
  import "./chunk-KU6HF2EW.js";
7
12
  import "./chunk-TW7KYJQ6.js";
8
13
  import "./chunk-463H6B56.js";
@@ -11,21 +16,8 @@ import "./chunk-GNPFWISJ.js";
11
16
  // src/routes.ts
12
17
  var table = {};
13
18
  var outlets = /* @__PURE__ */ new Set();
14
- var compiled = /* @__PURE__ */ new Map();
15
- function compile(pattern) {
16
- let re = compiled.get(pattern);
17
- if (!re) {
18
- const body = pattern.replace(/\/\*$|^\*$/, "\0").replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/:(\w+)/g, "(?<$1>[^/]+)").replace(/\/$/, "").replace("\0", "(?:/.*)?");
19
- compiled.set(pattern, re = new RegExp(`^${body}/?$`));
20
- }
21
- return re;
22
- }
23
- function matchRoute(path, routes2 = table) {
24
- for (const [pattern, name] of Object.entries(routes2)) {
25
- const m = compile(pattern).exec(path);
26
- if (m) return { name, pattern, params: { ...m.groups } };
27
- }
28
- return null;
19
+ function matchRoute2(path, routes2 = table) {
20
+ return matchRoute(path, routes2);
29
21
  }
30
22
  function routes(map, options = {}) {
31
23
  table = map;
@@ -44,7 +36,7 @@ function onClick(e) {
44
36
  const a = e.composedPath().find((n) => n.localName === "a" && !!n.href);
45
37
  if (!a || a.target && a.target !== "_self" || a.hasAttribute("download")) return;
46
38
  const url = new URL(a.href);
47
- if (url.origin !== location.origin || !matchRoute(url.pathname)) return;
39
+ if (url.origin !== location.origin || !matchRoute2(url.pathname)) return;
48
40
  e.preventDefault();
49
41
  navigate(url.href);
50
42
  }
@@ -99,7 +91,7 @@ var VitralOutletElement = class extends Base {
99
91
  }
100
92
  /** Confere a URL atual e troca de remote se a rota mudou. */
101
93
  sync() {
102
- if (this.isConnected) this.#show(matchRoute(location.pathname)?.name ?? null);
94
+ if (this.isConnected) this.#show(matchRoute2(location.pathname)?.name ?? null);
103
95
  }
104
96
  #show(name) {
105
97
  if (name === this.#route) return;
@@ -113,12 +105,24 @@ var VitralOutletElement = class extends Base {
113
105
  } else if (this.#slot) {
114
106
  this.#slot.set({ name });
115
107
  } else {
116
- this.#slot = createSlot(this, {
108
+ const options = {
117
109
  name,
118
110
  props: this.#props,
119
111
  isolate: this.getAttribute("isolate") || void 0,
120
112
  onStatus: (s, e) => this.#status(s, e)
121
- });
113
+ };
114
+ const ssr = this.querySelector(":scope>[data-vitral-ssr]");
115
+ if (ssr?.getAttribute("data-vitral-slot") === name) {
116
+ this.#status("loading", null);
117
+ warmSsr(ssr);
118
+ import("./hydrate-NFZZMYWT.js").then((m) => {
119
+ if (this.#route === name && !this.#slot) this.#slot = m.hydrateSlot(this, ssr, { ...options, props: this.#props });
120
+ else ssr.remove();
121
+ });
122
+ return;
123
+ }
124
+ ssr?.remove();
125
+ this.#slot = createSlot(this, options);
122
126
  }
123
127
  }
124
128
  #status(status, error) {
@@ -139,6 +143,6 @@ function defineVitralOutlet(tag = "vitral-outlet") {
139
143
  export {
140
144
  VitralOutletElement,
141
145
  defineVitralOutlet,
142
- matchRoute,
146
+ matchRoute2 as matchRoute,
143
147
  routes
144
148
  };
@@ -1,4 +1,4 @@
1
- import { P as Props, a as RemoteModule } from './types-DUtcF3HO.js';
1
+ import { P as Props, a as RemoteModule } from './types-EOz1rOHs.js';
2
2
  import './errors-kjBv6IH_.js';
3
3
 
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { R as RemoteError } from './errors-kjBv6IH_.js';
2
- import { P as Props, I as Isolation, d as StyleOptions } from './types-DUtcF3HO.js';
2
+ import { P as Props, I as Isolation, d as StyleOptions } from './types-EOz1rOHs.js';
3
3
 
4
4
  type SlotStatus = 'loading' | 'ready' | 'error';
5
5
  interface SlotOptions<P extends Props = Props> {
package/dist/solid.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { JSX, Component, Accessor } from 'solid-js';
2
- import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared } from './types-DUtcF3HO.js';
3
- export { R as RemoteContext } from './types-DUtcF3HO.js';
2
+ import { P as Props, I as Isolation, C as CheckedProps, a as RemoteModule, S as Shared } from './types-EOz1rOHs.js';
3
+ export { R as RemoteContext } from './types-EOz1rOHs.js';
4
4
  import { R as RemoteError } from './errors-kjBv6IH_.js';
5
- export { e as events } from './events-0rxFlWJJ.js';
5
+ export { e as events } from './events-DLdbFqBM.js';
6
6
  export { n as navigate } from './navigate-BRG1WJUM.js';
7
7
  import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
8
8
 
package/dist/solid.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  hostSlot
3
- } from "./chunk-4Z77XNBR.js";
3
+ } from "./chunk-TXSHK3SK.js";
4
4
  import {
5
5
  defineRemote,
6
6
  events,
@@ -8,8 +8,8 @@ import {
8
8
  navigate,
9
9
  same,
10
10
  shared
11
- } from "./chunk-KZBH5MPD.js";
12
- import "./chunk-5JNV45BB.js";
11
+ } from "./chunk-O7DV3EVB.js";
12
+ import "./chunk-72H4FXMD.js";
13
13
  import "./chunk-KU6HF2EW.js";
14
14
  import "./chunk-TW7KYJQ6.js";
15
15
  import "./chunk-463H6B56.js";
@@ -0,0 +1,15 @@
1
+ // src/core/stale.ts
2
+ function stale(url, fresh, maxStale) {
3
+ const key = "vitral:manifest:" + url;
4
+ fresh.then((m) => localStorage[key] = JSON.stringify({ t: Date.now(), m })).catch(() => {
5
+ });
6
+ try {
7
+ const saved = JSON.parse(localStorage[key]);
8
+ if (Date.now() - saved.t < maxStale * 1e3) return saved.m;
9
+ } catch {
10
+ }
11
+ return fresh;
12
+ }
13
+ export {
14
+ stale
15
+ };
package/dist/svelte.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { Component } from 'svelte';
2
- import { P as Props, I as Isolation, a as RemoteModule } from './types-DUtcF3HO.js';
3
- export { R as RemoteContext } from './types-DUtcF3HO.js';
2
+ import { P as Props, I as Isolation, a as RemoteModule } from './types-EOz1rOHs.js';
3
+ export { R as RemoteContext } from './types-EOz1rOHs.js';
4
4
  import { R as RemoteError } from './errors-kjBv6IH_.js';
5
- import { S as SlotStatus } from './slot-D49L1rdU.js';
6
- export { e as events } from './events-0rxFlWJJ.js';
5
+ import { S as SlotStatus } from './slot-Ddzp7AgL.js';
6
+ export { e as events } from './events-DLdbFqBM.js';
7
7
  export { n as navigate } from './navigate-BRG1WJUM.js';
8
8
  import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
9
9
 
package/dist/svelte.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  hostSlot
3
- } from "./chunk-4Z77XNBR.js";
3
+ } from "./chunk-TXSHK3SK.js";
4
4
  import {
5
5
  defineRemote,
6
6
  events,
7
7
  navigate
8
- } from "./chunk-KZBH5MPD.js";
9
- import "./chunk-5JNV45BB.js";
8
+ } from "./chunk-O7DV3EVB.js";
9
+ import "./chunk-72H4FXMD.js";
10
10
  import "./chunk-KU6HF2EW.js";
11
11
  import "./chunk-TW7KYJQ6.js";
12
12
  import "./chunk-463H6B56.js";
package/dist/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as Props, R as RemoteContext, a as RemoteModule } from './types-DUtcF3HO.js';
1
+ import { P as Props, R as RemoteContext, a as RemoteModule } from './types-EOz1rOHs.js';
2
2
  export { r as resetVitral } from './state-BDdCwc21.js';
3
3
  import './errors-kjBv6IH_.js';
4
4
 
package/dist/testing.js CHANGED
@@ -4,10 +4,10 @@ import {
4
4
  harness,
5
5
  verify
6
6
  } from "./chunk-DAESKNQ6.js";
7
- import "./chunk-KZBH5MPD.js";
7
+ import "./chunk-O7DV3EVB.js";
8
8
  import {
9
9
  register
10
- } from "./chunk-5JNV45BB.js";
10
+ } from "./chunk-72H4FXMD.js";
11
11
  import "./chunk-KU6HF2EW.js";
12
12
  import "./chunk-TW7KYJQ6.js";
13
13
  import "./chunk-463H6B56.js";
@@ -290,6 +290,14 @@ interface VitralConfig {
290
290
  timeout?: number;
291
291
  /** Tentativas extras se o download falhar. Padrão 1. */
292
292
  retries?: number;
293
+ /**
294
+ * Usa o `vitral.json` salvo na última visita, se tiver até N segundos, sem
295
+ * esperar a rede; o manifesto novo baixa por trás e vale na visita seguinte.
296
+ * Poupa uma ida e volta por remote na visita de volta. Um deploy (ou um
297
+ * rollback) chega a quem já tinha a cópia salva uma visita depois. Padrão:
298
+ * desligado (sempre revalida).
299
+ */
300
+ maxStale?: number;
293
301
  /** Isolamento padrão para todos os remotes. Padrão `'none'`. */
294
302
  isolate?: Isolation;
295
303
  /**
package/dist/vite.d.ts CHANGED
@@ -98,6 +98,13 @@ interface VitralViteOptions extends CssBuildOptions {
98
98
  * (`canal.json`). Usa `version` (ou a do package.json). Padrão: false.
99
99
  */
100
100
  versionDir?: boolean;
101
+ /**
102
+ * Põe o compile hint do V8 (`//# allFunctionsCalledOnLoad`) nos arquivos
103
+ * que rodam ao montar o remote, para o Chrome compilá-los de uma vez numa
104
+ * thread de fundo. Ajuda em CPU lenta e custa memória (veja o guia de
105
+ * carregamento). Os outros navegadores ignoram. Padrão: false.
106
+ */
107
+ compileHints?: boolean;
101
108
  }
102
109
  declare function vitral(options?: VitralViteOptions): Plugin;
103
110
 
package/dist/vite.js CHANGED
@@ -38,13 +38,15 @@ import { readFileSync, rmSync, writeFileSync } from "fs";
38
38
  import { join, posix } from "path";
39
39
  var SPLIT = "split/";
40
40
  var sri = (file) => "sha384-" + createHash("sha384").update(readFileSync(file)).digest("base64");
41
- function outputs(rolldown) {
41
+ function outputs(rolldown, hints = false) {
42
+ const banner = hints ? { banner: compileHint } : {};
42
43
  return [
43
- { format: "es", ...rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
44
+ { format: "es", ...banner, ...rolldown ? { codeSplitting: false } : { inlineDynamicImports: true } },
44
45
  // Os assets saem com o mesmo nome nas duas (o Vite só aceita um padrão).
45
- { format: "es", entryFileNames: `${SPLIT}remote-[hash].js`, chunkFileNames: `${SPLIT}[name]-[hash].js` }
46
+ { format: "es", ...banner, entryFileNames: `${SPLIT}remote-[hash].js`, chunkFileNames: `${SPLIT}[name]-[hash].js` }
46
47
  ];
47
48
  }
49
+ var compileHint = (chunk) => chunk.isEntry || !chunk.isDynamicEntry || chunk.name?.startsWith("_vitral") ? "//# allFunctionsCalledOnLoad" : "";
48
50
  var isSplit = (bundle) => Object.values(bundle).some((f) => f.type === "chunk" && f.isEntry && f.fileName.startsWith(SPLIT));
49
51
  var helper = (load = "import", base = "import.meta.url") => `function __vitralImport(u,d){var p=globalThis[Symbol.for("vitral")],s=p&&p.sri,a=d.concat(u).map(function(x){return new URL(x,${base}).href});return Promise.all(s?a.map(function(h){return new Promise(function(ok,no){if(!s[h])return no(new Error("vitral: arquivo sem integrity: "+h));var l=document.createElement("link");l.rel="modulepreload";l.crossOrigin="anonymous";l.integrity=s[h];l.href=h;l.onload=ok;l.onerror=function(){no(new Error("vitral: integrity n\xE3o confere: "+h))};document.head.appendChild(l)})}):[]).then(function(){return ${load}(a[a.length-1])})}`;
50
52
  function collect(outDir, bundle) {
@@ -887,7 +889,7 @@ function vitral(options = {}) {
887
889
  // Nomes com hash: cache eterno no CDN. Só o vitral.json muda a cada deploy.
888
890
  lib: { entry: dedupe ? BOOT : options.exposes ? EXPOSES_ENTRY : options.adapter === false ? entry : ENTRY_ID, fileName: () => "remote-[hash].js", cssFileName: "remote" },
889
891
  // Arquivo único (hosts antigos e caminho com blob:) e build dividido (manifesto v2).
890
- rollupOptions: { external: options.shared ?? [], output: outputs(rolldown) },
892
+ rollupOptions: { external: options.shared ?? [], output: outputs(rolldown, !!options.compileHints) },
891
893
  cssCodeSplit: false,
892
894
  ...dir && { outDir: dir }
893
895
  }
package/dist/vue.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as vue from 'vue';
2
2
  import { PropType, App, ShallowRef, WritableComputedRef, ComputedRef, Component } from 'vue';
3
- import { P as Props, I as Isolation, R as RemoteContext, S as Shared, a as RemoteModule } from './types-DUtcF3HO.js';
4
- export { e as events } from './events-0rxFlWJJ.js';
3
+ import { P as Props, I as Isolation, R as RemoteContext, S as Shared, a as RemoteModule } from './types-EOz1rOHs.js';
4
+ export { e as events } from './events-DLdbFqBM.js';
5
5
  import { L as Loading, P as Prefetch } from './host-slot-Cz6EiGsB.js';
6
6
  import './errors-kjBv6IH_.js';
7
7