vitral 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +357 -2
  3. package/dist/angular.d.ts +38 -0
  4. package/dist/angular.js +90 -0
  5. package/dist/auto.d.ts +2 -0
  6. package/dist/auto.js +12 -0
  7. package/dist/chunk-2XF5BKV3.js +190 -0
  8. package/dist/chunk-6Y3VMWHH.js +181 -0
  9. package/dist/chunk-DXORSF4X.js +42 -0
  10. package/dist/chunk-GNPFWISJ.js +80 -0
  11. package/dist/chunk-HP6QWU6K.js +51 -0
  12. package/dist/chunk-NCONW6WS.js +606 -0
  13. package/dist/chunk-PX7PBCCT.js +89 -0
  14. package/dist/chunk-S5MZT5IT.js +20 -0
  15. package/dist/chunk-SFL6LTP3.js +56 -0
  16. package/dist/chunk-UTYAX6MU.js +152 -0
  17. package/dist/cli.d.ts +1 -0
  18. package/dist/cli.js +88 -0
  19. package/dist/dedupe-IWFIXRWG.js +81 -0
  20. package/dist/devtools.d.ts +12 -0
  21. package/dist/devtools.js +86 -0
  22. package/dist/element.d.ts +88 -0
  23. package/dist/element.js +18 -0
  24. package/dist/errors-KKB8FGCz.d.ts +11 -0
  25. package/dist/events-DUdjhfps.d.ts +6 -0
  26. package/dist/expose-53BEJB34.js +14 -0
  27. package/dist/host-slot-Cz6EiGsB.d.ts +6 -0
  28. package/dist/iframe.d.ts +28 -0
  29. package/dist/iframe.js +236 -0
  30. package/dist/index.d.ts +186 -0
  31. package/dist/index.js +65 -0
  32. package/dist/navigate-BRG1WJUM.d.ts +9 -0
  33. package/dist/overrides-NZAIUGK5.js +15 -0
  34. package/dist/preact.d.ts +45 -0
  35. package/dist/preact.js +71 -0
  36. package/dist/react.d.ts +63 -0
  37. package/dist/react.js +167 -0
  38. package/dist/routes.d.ts +56 -0
  39. package/dist/routes.js +143 -0
  40. package/dist/shadow-MYRJQLLY.js +72 -0
  41. package/dist/slot-pB276oPt.d.ts +36 -0
  42. package/dist/solid.d.ts +47 -0
  43. package/dist/solid.js +83 -0
  44. package/dist/sri-BVKZNX5Q.js +114 -0
  45. package/dist/state-BDdCwc21.d.ts +4 -0
  46. package/dist/svelte.d.ts +43 -0
  47. package/dist/svelte.js +42 -0
  48. package/dist/testing.d.ts +28 -0
  49. package/dist/testing.js +52 -0
  50. package/dist/types-BV-hUrms.d.ts +265 -0
  51. package/dist/vite.d.ts +78 -0
  52. package/dist/vite.js +786 -0
  53. package/dist/vue.d.ts +133 -0
  54. package/dist/vue.js +148 -0
  55. package/package.json +331 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 João (joaogabriel15)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,358 @@
1
- # Temporary Holding Version
1
+ <p align="center"><img src="https://raw.githubusercontent.com/joaogabriel15/vitral/main/docs/logo.svg" width="96" alt="vitral"></p>
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <h1 align="center">vitral</h1>
4
+
5
+ <p align="center"><strong>Feito de partes. Visto como um todo.</strong></p>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/joaogabriel15/vitral/actions/workflows/ci.yml"><img src="https://github.com/joaogabriel15/vitral/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
9
+ <a href="https://www.npmjs.com/package/vitral"><img src="https://img.shields.io/npm/v/vitral" alt="npm"></a>
10
+ <a href="https://bundlejs.com/?q=vitral"><img src="https://img.shields.io/bundlejs/size/vitral" alt="tamanho"></a>
11
+ <a href="https://github.com/joaogabriel15/vitral/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/vitral" alt="licença MIT"></a>
12
+ </p>
13
+
14
+ Junte micro-frontends de qualquer framework numa página só, sem configuração de build no host.
15
+
16
+ ```bash
17
+ npm install vitral
18
+ ```
19
+
20
+ - O host só precisa da URL de cada remote.
21
+ - React, Vue, Angular, Svelte, Solid, Preact, Lit e JS puro na mesma página.
22
+ - Cada remote tem o próprio CSS, os próprios erros e o próprio deploy.
23
+
24
+ ## Começo rápido
25
+
26
+ Para gerar host e remote prontos: `npm create vitral@latest`.
27
+
28
+ **1. No remote**, exporte o componente e use o plugin:
29
+
30
+ ```jsx
31
+ // src/App.jsx (ou .vue, .svelte, .tsx…)
32
+ export default function Carrinho({ userId }) { … }
33
+ ```
34
+
35
+ ```js
36
+ // vite.config.js
37
+ import react from '@vitejs/plugin-react'
38
+ import vitral from 'vitral/vite'
39
+
40
+ export default { plugins: [react(), vitral()] }
41
+ ```
42
+
43
+ O plugin descobre o framework e embrulha o `export default` com o adaptador certo. A entrada padrão é `src/remote.*` ou `src/App.*`.
44
+
45
+ `vite build` gera o JS, o CSS e um `vitral.json`. Publique a pasta `dist` em qualquer CDN com CORS.
46
+
47
+ **2. No host**, registre a URL e use o componente:
48
+
49
+ ```jsx
50
+ import { configure } from 'vitral'
51
+ import { Remote } from 'vitral/react'
52
+
53
+ configure({
54
+ remotes: { carrinho: 'https://cdn.empresa.com/carrinho/vitral.json' },
55
+ })
56
+
57
+ export function App() {
58
+ return (
59
+ <Remote
60
+ name="carrinho"
61
+ props={{ userId: 42 }}
62
+ fallback={<p>Carregando…</p>}
63
+ error={(erro, tentarDeNovo) => <button onClick={tentarDeNovo}>Tentar de novo</button>}
64
+ />
65
+ )
66
+ }
67
+ ```
68
+
69
+ Pronto. Mudar `props` atualiza o remote sem remontar.
70
+
71
+ Sem build no host, numa página HTML qualquer:
72
+
73
+ ```html
74
+ <script type="module" src="https://cdn.jsdelivr.net/npm/vitral/dist/auto.js"></script>
75
+ <vitral-remote src="https://cdn.empresa.com/carrinho/vitral.json"></vitral-remote>
76
+ ```
77
+
78
+ Todos os componentes de host aceitam `src` no lugar de `name`.
79
+
80
+ ## Frameworks
81
+
82
+ | Framework | Remote | Host | Import |
83
+ |---|---|---|---|
84
+ | React 18/19 | `reactRemote(App)` | `<Remote>` | `vitral/react` |
85
+ | Next.js (App e Pages Router) | `reactRemote(App)` | `<Remote>` | `vitral/react` |
86
+ | Vue 3 | `vueRemote(App, { setup })` | `<VitralRemote>` | `vitral/vue` |
87
+ | Nuxt 3/4 | `vueRemote(App, { setup })` | `<VitralRemote>` | `vitral/vue` |
88
+ | Angular 17+ | `angularRemote(Component, { providers })` | `<vitral-remote>` + `provideVitral()` | `vitral/angular` |
89
+ | Svelte 5 | `svelteRemote(App)` | `use:remote` | `vitral/svelte` |
90
+ | Solid | `solidRemote(App)` | `<Remote>` | `vitral/solid` |
91
+ | Preact | `preactRemote(App)` | `<Remote>` | `vitral/preact` |
92
+ | Lit e Web Components | `elementRemote('meu-widget')` | `<vitral-remote>` | `vitral/element` |
93
+ | JS e TypeScript puro | `component({ render })` | `<vitral-remote>` | `vitral` |
94
+
95
+ No Next e no Nuxt o componente renderiza o `fallback` no servidor e monta o remote no cliente.
96
+
97
+ ### Host em Vue
98
+
99
+ ```vue
100
+ <script setup>
101
+ import { VitralRemote } from 'vitral/vue'
102
+ </script>
103
+
104
+ <template>
105
+ <VitralRemote name="carrinho" :props="{ userId: 42 }">
106
+ <template #fallback>Carregando…</template>
107
+ <template #error="{ retry }"><button @click="retry">Tentar de novo</button></template>
108
+ </VitralRemote>
109
+ </template>
110
+ ```
111
+
112
+ ### Host em qualquer outro lugar
113
+
114
+ `<vitral-remote>` funciona em HTML puro, Angular, Svelte, Astro ou HTML gerado no servidor:
115
+
116
+ ```html
117
+ <script type="module">
118
+ import { configure } from 'vitral'
119
+ import { defineVitralElement } from 'vitral/element'
120
+
121
+ configure({ remotes: { carrinho: 'https://cdn.empresa.com/carrinho/vitral.json' } })
122
+ defineVitralElement()
123
+ </script>
124
+
125
+ <vitral-remote name="carrinho" props='{"userId": 42}'>
126
+ <p slot="fallback">Carregando…</p>
127
+ <p slot="error">Indisponível</p>
128
+ </vitral-remote>
129
+ ```
130
+
131
+ ### Remote sem framework
132
+
133
+ ```ts
134
+ import { component, html } from 'vitral'
135
+
136
+ export default component<{ nome: string }>({
137
+ state: { cliques: 0 },
138
+ render: ({ nome }, state) => html`
139
+ <p>Olá, ${nome}</p>
140
+ <button onclick=${() => state.cliques++}>cliques: ${state.cliques}</button>
141
+ `,
142
+ })
143
+ ```
144
+
145
+ O que entra em `${}` é escapado. Mudar `state` ou as props atualiza a tela.
146
+
147
+ ## Desenvolvimento
148
+
149
+ - **HMR:** com o remote em `vite dev`, aponte o host para `http://localhost:5174/vitral.json`. Editar o remote atualiza o host sem recarregar a página.
150
+ - **Overrides:** `http://localhost:3000/?vitral=carrinho@http://localhost:5174` troca a URL de um remote sem mexer no host. Só vale em `localhost` ou com `configure({ devOverrides: true })`. Para guardar no navegador, use `devtools()` de `vitral/devtools`.
151
+ - **Tipos das props:** o build publica `vitral.d.ts`. No host, `npx vitral types` gera `vitral-env.d.ts`, e uma prop errada passa a não compilar.
152
+
153
+ ## Comunicação entre remotes
154
+
155
+ ```js
156
+ import { events } from 'vitral'
157
+
158
+ events.emit('carrinho:total', 120)
159
+ const parar = events.on('carrinho:total', (total) => console.log(total))
160
+ events.last('carrinho:total') // 120
161
+ ```
162
+
163
+ Todos os remotes usam o mesmo barramento. O que um remote assina é cancelado quando ele desmonta.
164
+
165
+ Para estado comum (usuário, tema, carrinho), use o contexto compartilhado:
166
+
167
+ ```js
168
+ import { provide, shared } from 'vitral'
169
+
170
+ provide('usuario', { id: 42 }) // host: cria e é o dono
171
+ provide('tema', 'claro', { writable: false }) // só o dono altera
172
+ shared('tema').subscribe((tema) => console.log(tema))
173
+ const nome = useShared('usuario', (u) => u?.nome) // React, Preact, Vue e Solid
174
+ ```
175
+
176
+ Angular usa `injectShared`, Svelte usa `$tema` e Lit usa `SharedController`. Detalhes em [Contexto compartilhado](https://joaogabriel15.github.io/vitral/aprender/contexto).
177
+
178
+ Para mudar de página de dentro de um remote, use `navigate('/pedidos/42')`. Todos os roteadores da página recebem a mudança.
179
+
180
+ ## CSS e Tailwind
181
+
182
+ Use Tailwind ou qualquer CSS no remote. O plugin prefixa o CSS para valer só dentro do remote, então o CSS de um remote não muda o host nem os outros remotes.
183
+
184
+ Para isolar por completo, use Shadow DOM:
185
+
186
+ ```jsx
187
+ <Remote name="carrinho" isolate="shadow" />
188
+ ```
189
+
190
+ Com Shadow DOM, as regras `@property` e `@font-face` sobem para o documento, então sombras, rings, gradientes e fontes do Tailwind v4 funcionam.
191
+
192
+ O remote também pode usar o tema do host:
193
+
194
+ ```js
195
+ vitral({ theme: 'host' }) // var(--x) usa o valor do host, se existir
196
+ configure({ styles: { inherit: ['/assets/base.css'] } }) // CSS base do host dentro do Shadow DOM
197
+ ```
198
+
199
+ Tema com Tailwind v4, dark mode, CSS legado e Tailwind v3 no host: [Estilos](https://joaogabriel15.github.io/vitral/aprender/estilos).
200
+
201
+ ## Configuração
202
+
203
+ ```js
204
+ configure({
205
+ remotes: '/remotes.json', // ou { nome: url }
206
+ allowedOrigins: ['https://cdn.empresa.com'], // padrão: a página e as origens registradas
207
+ timeout: 15000, // ms por download
208
+ retries: 1, // novas tentativas em erro de rede
209
+ isolate: 'none', // ou 'shadow'
210
+ })
211
+ ```
212
+
213
+ Cada remote também aceita um objeto:
214
+
215
+ ```js
216
+ configure({
217
+ remotes: {
218
+ carrinho: { url: 'https://cdn.empresa.com/carrinho/vitral.json', integrity: 'sha384-…' },
219
+ menu: { module: () => import('./menu') }, // remote local, sem rede
220
+ },
221
+ })
222
+ ```
223
+
224
+ ## Erros
225
+
226
+ Todo erro é um `RemoteError` com `code`, o nome do remote e `docs`, o link da [página do erro](https://github.com/joaogabriel15/vitral/tree/main/docs/erros) com causas e correção. Um remote que falha mostra o próprio erro e não derruba a página. `retry` monta só aquele remote de novo.
227
+
228
+ | `code` | Quando |
229
+ |---|---|
230
+ | `NOT_REGISTERED` | Nome não registrado em `configure` |
231
+ | `ORIGIN_BLOCKED` | URL fora de `allowedOrigins` |
232
+ | `TIMEOUT` | Não respondeu dentro de `timeout` |
233
+ | `INTEGRITY` | O hash do JS não confere |
234
+ | `INVALID_MODULE` | O arquivo não exporta `mount()` |
235
+ | `LOAD_FAILED` | Erro de rede ou HTTP |
236
+ | `MOUNT_FAILED` | O remote lançou erro ao montar |
237
+ | `RENDER_FAILED` | O remote quebrou depois de montado |
238
+
239
+ ## Performance
240
+
241
+ Remote com `import()` também gera `dist/split/`: o navegador baixa só o que o remote usa ao abrir, e o resto chega no `import()`, conferido pelo mesmo hash. Hosts antigos continuam usando o arquivo único.
242
+
243
+ No CDN, sirva `vitral.json` com `Cache-Control: no-cache` e o resto (nome com hash) com `public, max-age=31536000, immutable`.
244
+
245
+
246
+ Assim que o manifesto chega, o JS e o CSS do remote baixam juntos. A montagem
247
+ espera os dois, para o remote não aparecer sem estilo. `configure()` abre a
248
+ conexão com a origem de cada remote (`<link rel="preconnect">`).
249
+
250
+ ```js
251
+ import { preload } from 'vitral'
252
+ // Baixa JS e CSS sem montar, por exemplo no hover de um link
253
+ link.addEventListener('pointerenter', () => preload('checkout'), { once: true })
254
+ ```
255
+
256
+ Nos componentes de host e no `<vitral-remote>`:
257
+
258
+ ```html
259
+ <!-- monta perto de aparecer na tela; reserve o espaço para a página não pular -->
260
+ <vitral-remote name="comentarios" loading="lazy" style="display:block;min-height:400px"></vitral-remote>
261
+ <!-- monta com o navegador ocioso, mas já baixa no hover -->
262
+ <vitral-remote name="checkout" loading="idle" prefetch="hover"></vitral-remote>
263
+ <!-- remote que aparece logo ao abrir a página -->
264
+ <vitral-remote name="cabecalho" priority="high"></vitral-remote>
265
+ ```
266
+
267
+ ```jsx
268
+ <Remote name="checkout" loading="lazy" prefetch="visible" keepAlive />
269
+ ```
270
+
271
+ | Opção | Valores | O que faz |
272
+ | --- | --- | --- |
273
+ | `loading` | `lazy`, `idle` | Monta a 200px de aparecer na tela, ou com o navegador ocioso |
274
+ | `prefetch` | `hover`, `visible`, `idle` | Chama `preload()` antes de montar |
275
+ | `priority` | `high` | `fetchpriority` alto no manifesto, no JS e no CSS |
276
+ | `keepAlive` (`keep-alive`) | `true` ou o máximo | Ao sair da página, o remote vai para um contêiner oculto (LRU, padrão 5); na volta só recebe as props novas |
277
+
278
+ Com keep-alive, o remote pode pausar timers e assinaturas:
279
+
280
+ ```js
281
+ mount(el, props, ctx) {
282
+ ctx.onDeactivate?.(() => clearInterval(timer))
283
+ ctx.onActivate?.(() => (timer = setInterval(tick, 1000)))
284
+ }
285
+ ```
286
+
287
+ ### Métricas
288
+
289
+ Cada etapa do carregamento vira um `performance.measure` com o nome
290
+ `vitral:<remote>:<etapa>`. As etapas são `manifest`, `js`, `css` e `mount`.
291
+ Elas aparecem na aba Performance do DevTools. Para mandar ao seu RUM:
292
+
293
+ ```js
294
+ configure({
295
+ onMetric: ({ name, stage, duration }) => rum.send(`vitral.${stage}`, duration, { remote: name }),
296
+ })
297
+ ```
298
+
299
+ O evento `vitral-ready` (e o `ready` do componente Vue) traz os tempos em
300
+ `detail.timings`, por exemplo `{ manifest: 12.3, js: 40.1, css: 8, mount: 2.4 }`.
301
+ Um remote local (`module`) só mede `css` e `mount`. Erros dentro do
302
+ `onMetric` são ignorados.
303
+
304
+ ## Dependências compartilhadas
305
+
306
+ Para não baixar React ou Vue mais de uma vez, liste-os em `dedupe` no remote:
307
+
308
+ ```js
309
+ vitral({ dedupe: ['react'] })
310
+ ```
311
+
312
+ O remote usa a cópia que já está na página quando a versão serve (padrão: `^` da versão instalada no remote) e baixa a própria só quando não serve. Os componentes de host em React oferecem o React do host sem configuração.
313
+
314
+ ### Mais formas de usar
315
+
316
+ Vários componentes por remote (`<Remote name="carrinho/MiniCarrinho" />`),
317
+ módulos sem UI (`loadModule('carrinho/api')`), deploy novo sem recarregar a
318
+ página (`watchUpdates()` e `refresh('carrinho')`) e app shell por rota
319
+ (`routes()` e `<vitral-outlet>`, em `vitral/routes`). Veja
320
+ [Exposes](https://joaogabriel15.github.io/vitral/aprender/exposes), [Atualização sem reload](https://joaogabriel15.github.io/vitral/aprender/atualizacoes) e [Rotas](https://joaogabriel15.github.io/vitral/aprender/rotas).
321
+
322
+ ## Segurança
323
+
324
+ - Só importa JS de origens permitidas, mesmo que o `vitral.json` aponte para outra. O `src` de um componente de host entra na allowlist; o atributo `src` do `<vitral-remote>` não entra quando há `allowedOrigins`.
325
+ - Com `integrity`, nada roda sem o hash conferir. A lib usa o primeiro caminho que o navegador garante: import map com `integrity` (Chrome 133+, Safari 18.4+), `<link rel="modulepreload" integrity>` (Firefox 115+) ou, nos outros, baixa, confere e executa exatamente os bytes conferidos via `blob:`. Aceita `sha256`, `sha384` e `sha512`, e vários hashes separados por espaço (vale o mais forte). O CSS do manifesto também é conferido.
326
+ - Com CSP, a lib copia o `nonce` de um `<script nonce>` da página para o import map. Sem nonce, cai para o `modulepreload`.
327
+ - O hash só protege contra CDN comprometido se vier de outro lugar: fixe `integrity` no host ou embuta o manifesto (`{ url, manifest }`).
328
+ - Sem `eval` e sem iframes.
329
+ - Shadow DOM isola o CSS, não o JS. Para código de terceiros em que você não confia, use iframe.
330
+
331
+ ## Testes do host
332
+
333
+ ```ts
334
+ import { mockRemote, failingRemote } from 'vitral/testing'
335
+
336
+ const carrinho = mockRemote('carrinho', (el, props) => (el.textContent = `itens: ${props.itens}`))
337
+ // renderize o host
338
+ expect(carrinho.lastProps).toEqual({ itens: 2 })
339
+
340
+ failingRemote('recomendacoes') // testa a tela de erro
341
+ ```
342
+
343
+ ## Comparado com Module Federation e single-spa
344
+
345
+ | | Module Federation / single-spa | vitral |
346
+ |---|---|---|
347
+ | Build do host | Config combinada com cada remote | Nenhuma. Só `configure()` |
348
+ | Versões de React/Vue | `shared` e singletons, conflitos de versão | Cada remote leva a sua. Compartilhar é opcional |
349
+ | Remote fora do ar | Pode derrubar a página | Só aquele remote mostra erro |
350
+ | CSS | Vaza entre apps | Escopo automático ou Shadow DOM |
351
+ | Deploy novo | `ChunkLoadError` com cache velho | Arquivos com hash; só o `vitral.json` revalida |
352
+ | Conceitos | Containers, exposes, lifecycles, root config | `mount(el, props, ctx)` → `{ update, unmount }` |
353
+
354
+ ## Links
355
+
356
+ - [Exemplos](https://github.com/joaogabriel15/vitral/tree/main/examples): o mesmo remote em 8 frameworks e 9 hosts.
357
+ - [Como contribuir](https://github.com/joaogabriel15/vitral/blob/main/CONTRIBUTING.md)
358
+ - Licença [MIT](https://github.com/joaogabriel15/vitral/blob/main/LICENSE)
@@ -0,0 +1,38 @@
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-BV-hUrms.js';
3
+ export { e as events } from './events-DUdjhfps.js';
4
+ export { n as navigate } from './navigate-BRG1WJUM.js';
5
+
6
+ /**
7
+ * Adaptador Angular (standalone, zoneless ou com zone.js).
8
+ *
9
+ * Remote: export default angularRemote(AppComponent, { providers: [provideHttpClient()] })
10
+ * Props viram inputs (`input()` ou `@Input()`); o contexto vem de `inject(VITRAL_CONTEXT)`.
11
+ *
12
+ * Host: providers: [provideVitral({ remotes: '/remotes.json' })]
13
+ * schemas: [CUSTOM_ELEMENTS_SCHEMA]
14
+ * <vitral-remote name="carrinho" [props]="{ userId }" isolate="shadow"></vitral-remote>
15
+ */
16
+
17
+ declare const VITRAL_CONTEXT: InjectionToken<RemoteContext>;
18
+ /** Transforma um componente standalone em um remote. */
19
+ declare function angularRemote<P extends Props>(component: Type<unknown>, config?: Partial<ApplicationConfig>): RemoteModule<P>;
20
+ /** Dentro de um remote Angular: `const vitral = injectVitral()`. */
21
+ declare function injectVitral(): RemoteContext | null;
22
+ /**
23
+ * Signal de uma chave compartilhada (`provide`/`shared`). Com seletor, só
24
+ * muda quando o resultado do seletor muda (`Object.is`). Chame num contexto de
25
+ * injeção (construtor, inicializador de campo); a assinatura acaba no destroy.
26
+ *
27
+ * usuario = injectShared('usuario')
28
+ * nome = injectShared('usuario', (u) => u?.nome)
29
+ */
30
+ declare function injectShared<K extends keyof Shared, S = Shared[K] | undefined>(key: K, select?: (value: Shared[K] | undefined) => S): Signal<S>;
31
+ declare function injectShared<T = unknown, S = T | undefined>(key: string, select?: (value: T | undefined) => S): Signal<S>;
32
+ /**
33
+ * Host Angular: configura o vitral e registra `<vitral-remote>`. Use junto com
34
+ * `CUSTOM_ELEMENTS_SCHEMA` no componente que renderiza o remote.
35
+ */
36
+ declare function provideVitral(config?: VitralConfig): (Provider | EnvironmentProviders)[];
37
+
38
+ export { VITRAL_CONTEXT, angularRemote, injectShared, injectVitral, provideVitral };
@@ -0,0 +1,90 @@
1
+ import {
2
+ defineVitralElement
3
+ } from "./chunk-6Y3VMWHH.js";
4
+ import "./chunk-UTYAX6MU.js";
5
+ import {
6
+ defineRemote,
7
+ events,
8
+ memoSelect,
9
+ navigate,
10
+ same,
11
+ shared
12
+ } from "./chunk-NCONW6WS.js";
13
+ import {
14
+ configure
15
+ } from "./chunk-2XF5BKV3.js";
16
+ import "./chunk-SFL6LTP3.js";
17
+ import "./chunk-PX7PBCCT.js";
18
+ import "./chunk-GNPFWISJ.js";
19
+
20
+ // src/angular.ts
21
+ import {
22
+ DestroyRef,
23
+ InjectionToken,
24
+ createComponent,
25
+ inject,
26
+ provideAppInitializer,
27
+ provideZonelessChangeDetection,
28
+ reflectComponentType,
29
+ signal
30
+ } from "@angular/core";
31
+ import { createApplication } from "@angular/platform-browser";
32
+ var VITRAL_CONTEXT = new InjectionToken("vitral.context");
33
+ function angularRemote(component, config = {}) {
34
+ const inputs = new Set((reflectComponentType(component)?.inputs ?? []).map((i) => i.templateName));
35
+ return defineRemote({
36
+ async mount(el, props, ctx) {
37
+ const app = await createApplication({
38
+ providers: [provideZonelessChangeDetection(), { provide: VITRAL_CONTEXT, useValue: ctx }, ...config.providers ?? []]
39
+ });
40
+ const hostElement = document.createElement("div");
41
+ el.appendChild(hostElement);
42
+ const ref = createComponent(component, { environmentInjector: app.injector, hostElement });
43
+ const apply = (p) => {
44
+ for (const [k, v] of Object.entries(p)) if (inputs.has(k)) ref.setInput(k, v);
45
+ };
46
+ apply(props);
47
+ app.attachView(ref.hostView);
48
+ ref.changeDetectorRef.detectChanges();
49
+ return {
50
+ update(next) {
51
+ apply(next);
52
+ app.tick();
53
+ },
54
+ unmount() {
55
+ app.destroy();
56
+ hostElement.remove();
57
+ }
58
+ };
59
+ }
60
+ });
61
+ }
62
+ function injectVitral() {
63
+ return inject(VITRAL_CONTEXT, { optional: true });
64
+ }
65
+ function injectShared(key, select = same) {
66
+ const destroy = inject(DestroyRef);
67
+ const handle = shared(key);
68
+ const pick = memoSelect();
69
+ const value = signal(pick(handle.get(), select), { equal: Object.is });
70
+ destroy.onDestroy(handle.subscribe((v) => value.set(pick(v, select))));
71
+ return value.asReadonly();
72
+ }
73
+ function provideVitral(config = {}) {
74
+ return [
75
+ provideAppInitializer(() => {
76
+ if (typeof window === "undefined") return;
77
+ configure(config);
78
+ defineVitralElement();
79
+ })
80
+ ];
81
+ }
82
+ export {
83
+ VITRAL_CONTEXT,
84
+ angularRemote,
85
+ events,
86
+ injectShared,
87
+ injectVitral,
88
+ navigate,
89
+ provideVitral
90
+ };
package/dist/auto.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/auto.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ defineVitralElement
3
+ } from "./chunk-6Y3VMWHH.js";
4
+ import "./chunk-UTYAX6MU.js";
5
+ import "./chunk-NCONW6WS.js";
6
+ import "./chunk-2XF5BKV3.js";
7
+ import "./chunk-SFL6LTP3.js";
8
+ import "./chunk-PX7PBCCT.js";
9
+ import "./chunk-GNPFWISJ.js";
10
+
11
+ // src/auto.ts
12
+ defineVitralElement();