vapor-chamber 1.3.0 → 1.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.
- package/README.md +133 -61
- package/ROADMAP.md +119 -19
- package/dist/alien-signals.d.ts +0 -15
- package/dist/alien-signals.d.ts.map +1 -1
- package/dist/alien-signals.js +87 -18
- package/dist/alien-signals.js.map +1 -1
- package/dist/{chamber-CesaYQmb.js → chamber-B3-zuvVj.js} +49 -19
- package/dist/chamber-B3-zuvVj.js.map +1 -0
- package/dist/{chamber-ayzW3B-v.js → chamber-B35FiYo8.js} +55 -25
- package/dist/chamber-B35FiYo8.js.map +1 -0
- package/dist/chamber-B5z-Gken.js +727 -0
- package/dist/chamber-B5z-Gken.js.map +1 -0
- package/dist/chamber-B7AzoeAj.js +718 -0
- package/dist/chamber-B7AzoeAj.js.map +1 -0
- package/dist/chamber-CExfKXYe.js +718 -0
- package/dist/chamber-CExfKXYe.js.map +1 -0
- package/dist/chamber-DqVl7_rP.js +689 -0
- package/dist/chamber-DqVl7_rP.js.map +1 -0
- package/dist/chamber-FNs5VA9n.js +727 -0
- package/dist/chamber-FNs5VA9n.js.map +1 -0
- package/dist/chamber-HVvu4D8h.js +727 -0
- package/dist/chamber-HVvu4D8h.js.map +1 -0
- package/dist/chamber-NzjDcpvJ.js +685 -0
- package/dist/chamber-NzjDcpvJ.js.map +1 -0
- package/dist/chamber-SVxj3n8C.js +718 -0
- package/dist/chamber-SVxj3n8C.js.map +1 -0
- package/dist/chamber-s5KoLmln.js +718 -0
- package/dist/chamber-s5KoLmln.js.map +1 -0
- package/dist/{chamber-vapor-Djf77X57.js → chamber-vapor-B7zy4F_Q.js} +36 -16
- package/dist/chamber-vapor-B7zy4F_Q.js.map +1 -0
- package/dist/chamber-vapor-BP7zdL8X.js +722 -0
- package/dist/chamber-vapor-BP7zdL8X.js.map +1 -0
- package/dist/chamber-vapor-BUuMJm5w.js +723 -0
- package/dist/chamber-vapor-BUuMJm5w.js.map +1 -0
- package/dist/chamber-vapor-BfGH34E5.js +722 -0
- package/dist/chamber-vapor-BfGH34E5.js.map +1 -0
- package/dist/chamber-vapor-C3pNqkBS.js +777 -0
- package/dist/chamber-vapor-C3pNqkBS.js.map +1 -0
- package/dist/chamber-vapor-CFQvlSLx.js +722 -0
- package/dist/chamber-vapor-CFQvlSLx.js.map +1 -0
- package/dist/chamber-vapor-ChLkr2Rf.js +779 -0
- package/dist/chamber-vapor-ChLkr2Rf.js.map +1 -0
- package/dist/chamber-vapor-CkXjdyD1.js +723 -0
- package/dist/chamber-vapor-CkXjdyD1.js.map +1 -0
- package/dist/chamber-vapor-DCS7qYS5.js +723 -0
- package/dist/chamber-vapor-DCS7qYS5.js.map +1 -0
- package/dist/{chamber-vapor-CqMH_L-d.js → chamber-vapor-DCb2sks_.js} +27 -7
- package/dist/chamber-vapor-DCb2sks_.js.map +1 -0
- package/dist/chamber-vapor-DxdPtv_K.js +783 -0
- package/dist/chamber-vapor-DxdPtv_K.js.map +1 -0
- package/dist/chamber-vapor-gp3UTXwG.js +722 -0
- package/dist/chamber-vapor-gp3UTXwG.js.map +1 -0
- package/dist/chamber-vapor.d.ts +61 -75
- package/dist/chamber-vapor.d.ts.map +1 -1
- package/dist/chamber.d.ts +62 -2
- package/dist/chamber.d.ts.map +1 -1
- package/dist/command-bus-4z9V4Dqv.js +1186 -0
- package/dist/command-bus-4z9V4Dqv.js.map +1 -0
- package/dist/command-bus-B7RiwMMZ.js +1183 -0
- package/dist/command-bus-B7RiwMMZ.js.map +1 -0
- package/dist/command-bus-BqLnO04I.js +1203 -0
- package/dist/command-bus-BqLnO04I.js.map +1 -0
- package/dist/command-bus-C7l2NaIg.js +1207 -0
- package/dist/command-bus-C7l2NaIg.js.map +1 -0
- package/dist/command-bus-D5vE6EbF.js +1198 -0
- package/dist/command-bus-D5vE6EbF.js.map +1 -0
- package/dist/command-bus-DIQ2OMsZ.js +1195 -0
- package/dist/command-bus-DIQ2OMsZ.js.map +1 -0
- package/dist/{command-bus-DNHnswE_.js → command-bus-DkqAqiyu.js} +67 -11
- package/dist/command-bus-DkqAqiyu.js.map +1 -0
- package/dist/{command-bus-nxA-KYSC.js → command-bus-DvDSuDAp.js} +138 -111
- package/dist/command-bus-DvDSuDAp.js.map +1 -0
- package/dist/command-bus-b19UHyWE.js +1205 -0
- package/dist/command-bus-b19UHyWE.js.map +1 -0
- package/dist/command-bus.d.ts +54 -2
- package/dist/command-bus.d.ts.map +1 -1
- package/dist/directives.d.ts +20 -1
- package/dist/directives.d.ts.map +1 -1
- package/dist/directives.js +217 -127
- package/dist/directives.js.map +1 -1
- package/dist/fast-lane.js +54 -45
- package/dist/fast-lane.js.map +1 -1
- package/dist/iife.d.ts +3 -3
- package/dist/iife.d.ts.map +1 -1
- package/dist/iife.js +133 -82
- package/dist/iife.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1617 -1072
- package/dist/index.js.map +1 -1
- package/dist/observable.js +70 -43
- package/dist/observable.js.map +1 -1
- package/dist/plugins-core.d.ts +13 -0
- package/dist/plugins-core.d.ts.map +1 -1
- package/dist/plugins-extra.d.ts +103 -1
- package/dist/plugins-extra.d.ts.map +1 -1
- package/dist/plugins-schema.js +70 -62
- package/dist/plugins-schema.js.map +1 -1
- package/dist/reactive.d.ts +70 -0
- package/dist/reactive.d.ts.map +1 -0
- package/dist/reactive.js +41 -0
- package/dist/reactive.js.map +1 -0
- package/dist/signal-BHIggu6z.js +54 -0
- package/dist/signal-BHIggu6z.js.map +1 -0
- package/dist/signal-C7CsIk76.js +54 -0
- package/dist/signal-C7CsIk76.js.map +1 -0
- package/dist/signal-hV77MeQn.js +38 -0
- package/dist/signal-hV77MeQn.js.map +1 -0
- package/dist/signal.d.ts +16 -8
- package/dist/signal.d.ts.map +1 -1
- package/dist/ssr.d.ts +23 -1
- package/dist/ssr.d.ts.map +1 -1
- package/dist/ssr.js +66 -43
- package/dist/ssr.js.map +1 -1
- package/dist/transitions.d.ts +47 -4
- package/dist/transitions.d.ts.map +1 -1
- package/dist/transitions.js +127 -87
- package/dist/transitions.js.map +1 -1
- package/dist/transports-BuNVK1q1.js +975 -0
- package/dist/transports-BuNVK1q1.js.map +1 -0
- package/dist/transports-C6if1aky.js +975 -0
- package/dist/transports-C6if1aky.js.map +1 -0
- package/dist/transports-C9MPBKU0.js +973 -0
- package/dist/transports-C9MPBKU0.js.map +1 -0
- package/dist/transports-COF9n6gG.js +975 -0
- package/dist/transports-COF9n6gG.js.map +1 -0
- package/dist/{transports-Bnz6r6x5.js → transports-Cv9tsG7p.js} +48 -9
- package/dist/{transports-BSfLx9oG.js.map → transports-Cv9tsG7p.js.map} +1 -1
- package/dist/{transports-BSfLx9oG.js → transports-DEPw-_Ff.js} +48 -9
- package/dist/transports-DEPw-_Ff.js.map +1 -0
- package/dist/transports-DxJC-941.js +975 -0
- package/dist/transports-DxJC-941.js.map +1 -0
- package/dist/transports-E2ilyKOO.js +975 -0
- package/dist/transports-E2ilyKOO.js.map +1 -0
- package/dist/transports-G7ljsMAq.js +975 -0
- package/dist/transports-G7ljsMAq.js.map +1 -0
- package/dist/transports-O_b57fWF.js +975 -0
- package/dist/transports-O_b57fWF.js.map +1 -0
- package/dist/transports.d.ts +63 -0
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +3 -9
- package/dist/utilities.d.ts.map +1 -1
- package/dist/vapor-chamber-core.iife.js +1721 -1186
- package/dist/vapor-chamber-core.iife.js.map +1 -1
- package/dist/vapor-chamber-core.iife.min.js +1 -1
- package/dist/vapor-chamber-elements.iife.js +1907 -1278
- package/dist/vapor-chamber-elements.iife.js.map +1 -1
- package/dist/vapor-chamber-elements.iife.min.js +1 -1
- package/dist/vapor-chamber.iife.js +2889 -1990
- package/dist/vapor-chamber.iife.js.map +1 -1
- package/dist/vapor-chamber.iife.min.js +1 -1
- package/dist/vite-hmr.d.ts +33 -1
- package/dist/vite-hmr.d.ts.map +1 -1
- package/dist/vite-hmr.js +73 -38
- package/dist/vite-hmr.js.map +1 -1
- package/package.json +27 -12
- package/scripts/build.mjs +1 -0
- package/scripts/check-size.mjs +19 -3
- package/scripts/measure-loc.mjs +78 -0
- package/scripts/measure-size.mjs +101 -0
- package/dist/chamber-CesaYQmb.js.map +0 -1
- package/dist/chamber-ayzW3B-v.js.map +0 -1
- package/dist/chamber-vapor-CqMH_L-d.js.map +0 -1
- package/dist/chamber-vapor-Djf77X57.js.map +0 -1
- package/dist/command-bus-DNHnswE_.js.map +0 -1
- package/dist/command-bus-nxA-KYSC.js.map +0 -1
- package/dist/signal-DUZrcb-E.js +0 -35
- package/dist/signal-DUZrcb-E.js.map +0 -1
- package/dist/transports-Bnz6r6x5.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
A
|
|
6
|
+
A command bus built for <a href="https://github.com/vuejs/vue-vapor">Vue Vapor</a> — a ~4 KB brotli dispatch core with opt-in batteries, each 0 KB until imported. Vue 3.6 Vapor aligned. LGPL-2.1.
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
## What is Vapor Chamber?
|
|
10
10
|
|
|
11
|
-
Vapor Chamber is a **command bus for Vue 3.6+ Vapor mode**.
|
|
11
|
+
Vapor Chamber is a **command bus for Vue 3.6+ Vapor mode**. Every user action gets a single handler, a composable plugin pipeline, and signal-native reactive state — replacing scattered event listeners and prop-drilling with one predictable, testable flow.
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
14
|
import { createCommandBus, useCommand } from 'vapor-chamber';
|
|
@@ -23,12 +23,37 @@ bus.use(validator({ cartAdd: (cmd) => cmd.target.id ? null : 'Missing ID' }));
|
|
|
23
23
|
const { dispatch, loading, lastError } = useCommand('cartAdd');
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
**What's in the can** — a small core, and batteries you only pay for if you import them:
|
|
27
|
+
|
|
28
|
+
| | |
|
|
29
|
+
|---|---|
|
|
30
|
+
| **Core** (the bus) | dispatch/query/emit, plugin pipeline, wildcard listeners — framework-agnostic, no Vue import; `createCommandBus` tree-shakes to ~3.6 KB brotli (measured sizes: [docs/BUNDLE-SIZES.md](docs/BUNDLE-SIZES.md)) |
|
|
31
|
+
| **Vue composables** | `useCommand`, `useCommandState`, shared state, Vapor-mode (`defineVaporCommand`) and full Vapor wrappers |
|
|
32
|
+
| **Plugins** (opt-in) | logger, validator, history (undo/redo), debounce, throttle, retry, persist, cross-tab sync, serialize, idempotent, auth guard |
|
|
33
|
+
| **Transports** (opt-in) | HTTP bridge, WebSocket, SSE, Laravel Echo/Reverb |
|
|
34
|
+
| **Extras** (opt-in, own subpath each) | SSR dehydrate/rehydrate, form bus, HTTP client, schema validation, transitions bridge, devtools, Vite HMR, testing utilities |
|
|
35
|
+
|
|
36
|
+
- **Vue 3.6.0-beta.16 aligned** — signals, `onScopeDispose`, `getCurrentScope`, alien-signals internals; tracked per beta (see CHANGELOG)
|
|
37
|
+
- **One runtime dependency** (`alien-signals`); `sideEffects: false` — unimported modules tree-shake to zero
|
|
38
|
+
- **IIFE builds for no-bundler pages** — full ~10 KB / core & elements ~7 KB brotli (exact, always-current per-export table: [docs/BUNDLE-SIZES.md](docs/BUNDLE-SIZES.md), generated by `npm run size:doc`)
|
|
39
|
+
- **SSR support** — dehydrate on the server, replay on the client (see `vapor-chamber/ssr`; the shared-bus helper is per-process — concurrent SSR servers should pass a per-request bus explicitly)
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install vapor-chamber # npm registry (releases may lag the repo)
|
|
45
|
+
|
|
46
|
+
# or install straight from the repo — the authoritative source while Vue 3.6
|
|
47
|
+
# is in beta (a `prepare` script builds it on install):
|
|
48
|
+
npm install github:lucianofedericopereira/vapor-chamber
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Requires Node ≥20.19. Vue is an **optional** peer dep (≥3.5 for composables, ≥3.6.0-beta.16 for the full Vapor surface) — the core bus runs without Vue entirely.
|
|
52
|
+
|
|
53
|
+
**Using Astro?** See [examples/exo-astro](examples/exo-astro) — a declarative directive set
|
|
54
|
+
(`v-scope`, `v-command`, `v-bind-text`, `v-show`) over the vapor-chamber bus for coordinating
|
|
55
|
+
independent Astro page sections, with `onMissing: 'buffer'` (+ `bufferTTL`) so sections can
|
|
56
|
+
dispatch before their handlers hydrate.
|
|
32
57
|
|
|
33
58
|
---
|
|
34
59
|
|
|
@@ -130,7 +155,7 @@ vapor-chamber is built in layers. The **core** is framework-agnostic, has zero d
|
|
|
130
155
|
| Plugins | `plugins-io.ts` | 88% | ✅ Stable |
|
|
131
156
|
| Transport | `http.ts` | 80% | ✅ Stable |
|
|
132
157
|
| Transport | `transports.ts` | 91% | ✅ Stable |
|
|
133
|
-
| Vue | `chamber.ts` |
|
|
158
|
+
| Vue | `chamber.ts` | ~95% stmts / ~87% branch | ✅ Stable |
|
|
134
159
|
| Extras | `form.ts` | 99% | ✅ Stable |
|
|
135
160
|
| Extras | `schema.ts` | 92% | ✅ Stable |
|
|
136
161
|
| Vue 3.6 | `chamber-vapor.ts` | ✅ | ✅ Stable (unit-tested without Vue 3.6 runtime) |
|
|
@@ -149,6 +174,7 @@ Sub-path exports avoid pulling in optional modules:
|
|
|
149
174
|
'vapor-chamber/observable' → Symbol.observable interop — RxJS / xstream / callbag adapter
|
|
150
175
|
'vapor-chamber/standard-schema'→ Standard Schema v1 validator plugin (Zod / Valibot / ArkType compatible)
|
|
151
176
|
'vapor-chamber/alien-signals' → connector to use alien-signals as the underlying reactive primitive (non-Vue contexts)
|
|
177
|
+
'vapor-chamber/reactive' → opt-in DEEP reactivity: deepSignal + useDeepCommandState (nested-mutation tracking; the core signal() is shallow+fast by default)
|
|
152
178
|
'vapor-chamber/iife' → IIFE bundle (full)
|
|
153
179
|
'vapor-chamber/iife-core' → IIFE bundle (no Vapor custom-element, no Suspense paths)
|
|
154
180
|
'vapor-chamber/iife-elements' → IIFE bundle (core + Vapor custom-element)
|
|
@@ -161,9 +187,9 @@ audience, not by feature checklist.
|
|
|
161
187
|
|
|
162
188
|
| Variant | Audience | File | Min | Brotli | Gzip |
|
|
163
189
|
|-----------|----------------------------------------------|---------------------------------------|-------|--------|--------|
|
|
164
|
-
| core | Sprinkled JS on server-rendered pages (Blade, Rails, Django, .NET MVC, WordPress). You dispatch user actions to a backend over HTTP. | `vapor-chamber-core.iife.js` |
|
|
165
|
-
| elements | Embeddable widgets (chat bubbles, checkout buttons, third-party drop-ins). You ship a `<vc-widget>` custom element. | `vapor-chamber-elements.iife.js` |
|
|
166
|
-
| full | SPAs that grew big enough to want everything (realtime, undo/redo, persistence, full Vapor surface). | `vapor-chamber.iife.js` |
|
|
190
|
+
| core | Sprinkled JS on server-rendered pages (Blade, Rails, Django, .NET MVC, WordPress). You dispatch user actions to a backend over HTTP. | `vapor-chamber-core.iife.js` | 24.4 KB | 7.0 KB | 7.8 KB |
|
|
191
|
+
| elements | Embeddable widgets (chat bubbles, checkout buttons, third-party drop-ins). You ship a `<vc-widget>` custom element. | `vapor-chamber-elements.iife.js` | 25.9 KB | 7.4 KB | 8.3 KB |
|
|
192
|
+
| full | SPAs that grew big enough to want everything (realtime, undo/redo, persistence, full Vapor surface). | `vapor-chamber.iife.js` | 35.4 KB | 10.2 KB | 11.3 KB |
|
|
167
193
|
|
|
168
194
|
**What's in each variant**
|
|
169
195
|
|
|
@@ -203,15 +229,28 @@ audience, not by feature checklist.
|
|
|
203
229
|
<vc-cart sku="ABC-123"></vc-cart>
|
|
204
230
|
```
|
|
205
231
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
232
|
+
Sizes above are **minified brotli** (q=11) / gzip (-9); brotli is what hits the wire on
|
|
233
|
+
modern CDNs. The dispatch core alone (`createCommandBus`, tree-shaken) is **~3.6 KB brotli**.
|
|
234
|
+
These figures — and the per-export ESM sizes — are regenerated and **CI-verified fresh** in
|
|
235
|
+
**[docs/BUNDLE-SIZES.md](docs/BUNDLE-SIZES.md)** (the always-current source of truth, via
|
|
236
|
+
`npm run size:doc`); `npm run size:check` fails CI on any regression past the budget. The build
|
|
237
|
+
is `scripts/build.mjs` (Vite 8 / rolldown).
|
|
238
|
+
|
|
239
|
+
**Size by version** (IIFE brotli — `full` / `core` / `elements`):
|
|
240
|
+
|
|
241
|
+
| Version | full | core | elements | Notes |
|
|
242
|
+
|---------|-----:|-----:|---------:|-------|
|
|
243
|
+
| v1.2.0 | 8.7 | 6.1 | 6.4 | audience-split baseline |
|
|
244
|
+
| v1.6.0 (beta.15) | 10.4 | 7.1 | 7.5 | +realtime / undo-redo / `onMissing:'buffer'` / Echo |
|
|
245
|
+
| v1.7.0 (unreleased, beta.16) | **10.2** | **7.0** | **7.4** | Vite 8 / rolldown minifier — **smaller, no regression** |
|
|
246
|
+
|
|
247
|
+
The v1.2 → v1.6 growth tracked added capabilities (see CHANGELOG per version); the latest move
|
|
248
|
+
is a **decrease**. Verified each release against the prior baseline via `npm run size:check`.
|
|
210
249
|
|
|
211
250
|
> **Variant contents are not under semver before v2.0.** While Vue 3.6 is in
|
|
212
251
|
> beta, the lib reserves the right to move APIs between IIFE variants. ESM
|
|
213
252
|
> consumers (the `vapor-chamber` main entry) get the full surface and are
|
|
214
|
-
> unaffected. See [ROADMAP.md](
|
|
253
|
+
> unaffected. See [ROADMAP.md](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/ROADMAP.md).
|
|
215
254
|
|
|
216
255
|
---
|
|
217
256
|
|
|
@@ -221,23 +260,24 @@ API) — single source, multiple outputs.
|
|
|
221
260
|
npm install vapor-chamber
|
|
222
261
|
```
|
|
223
262
|
|
|
224
|
-
**Requirements:** Node.js ≥20.19.0 | Vue ≥3.5.0 (composables) or ≥3.6.0-beta.
|
|
263
|
+
**Requirements:** Node.js ≥20.19.0 | Vue ≥3.5.0 (composables) or ≥3.6.0-beta.16 (full Vapor) — optional peer dep | Vite ≥7.0.0 + `@vitejs/plugin-vue` ≥5.0.0 (only required for the `vapor-chamber/vite` HMR plugin and Vapor SFC support)
|
|
225
264
|
|
|
226
265
|
> **Beta tracking:** this lib follows Vue 3.6 while it is in beta. The Vapor
|
|
227
|
-
> wrappers
|
|
228
|
-
>
|
|
266
|
+
> wrappers are transitional surfaces that will realign once Vue 3.6 ships
|
|
267
|
+
> stable; the command composables are now consolidated into a single
|
|
268
|
+
> Vapor-safe `useCommand`. See [ROADMAP.md](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/ROADMAP.md)
|
|
229
269
|
> for what is stable today, what is transitional, and the v1.3 / v2 plan.
|
|
230
270
|
>
|
|
231
|
-
> **Performance & tuning:** see [docs/performance.md](
|
|
271
|
+
> **Performance & tuning:** see [docs/performance.md](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/docs/performance.md)
|
|
232
272
|
> for what's optimized by default, the consumer-facing tuning knobs
|
|
233
273
|
> (`persist({ coalesce: true })`, `configureUid`, `configureSignal`), variant
|
|
234
274
|
> selection guide, and a benchmark snapshot.
|
|
235
275
|
>
|
|
236
|
-
> **Laravel integration:** see [docs/integrations/laravel.md](
|
|
276
|
+
> **Laravel integration:** see [docs/integrations/laravel.md](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/docs/integrations/laravel.md)
|
|
237
277
|
> for the full backend deliverables list (route, controller, action classes,
|
|
238
278
|
> CSRF flows, Sanctum, Inertia coexistence, Filament panels, Reverb
|
|
239
279
|
> realtime, queued commands). Runnable PHP companions live in
|
|
240
|
-
> [examples/laravel-backend/](
|
|
280
|
+
> [examples/laravel-backend/](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples/laravel-backend).
|
|
241
281
|
>
|
|
242
282
|
> **API reference:** generate locally with `npm run docs` (TypeDoc → `docs/api/`).
|
|
243
283
|
> The generated site is `.gitignore`d so it stays fresh per release. Hosting it
|
|
@@ -484,7 +524,7 @@ Every dispatched command is auto-stamped with `meta`:
|
|
|
484
524
|
|
|
485
525
|
```typescript
|
|
486
526
|
bus.onAfter((cmd) => {
|
|
487
|
-
console.log(cmd.meta.id); // unique
|
|
527
|
+
console.log(cmd.meta.id); // unique id per dispatch (counter-based; UUID via configureUid)
|
|
488
528
|
console.log(cmd.meta.ts); // Date.now() timestamp
|
|
489
529
|
console.log(cmd.meta.correlationId); // trace ID for command chains
|
|
490
530
|
});
|
|
@@ -881,6 +921,26 @@ bus.use(createSseBridge({
|
|
|
881
921
|
}));
|
|
882
922
|
```
|
|
883
923
|
|
|
924
|
+
### createEchoBridge
|
|
925
|
+
|
|
926
|
+
Laravel Echo / Reverb realtime — subscribe public/private/presence channels and
|
|
927
|
+
route each broadcast to `bus.emit()`. You pass your own Echo instance, so the
|
|
928
|
+
library never imports `laravel-echo`:
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
import { createEchoBridge } from 'vapor-chamber/transports';
|
|
932
|
+
|
|
933
|
+
const realtime = createEchoBridge({
|
|
934
|
+
echo, // your configured laravel-echo / Reverb instance
|
|
935
|
+
channels: [
|
|
936
|
+
{ name: `user.${userId}`, type: 'private', events: ['OrderShipped'] },
|
|
937
|
+
{ name: 'lobby', type: 'presence', events: ['MessagePosted'] },
|
|
938
|
+
],
|
|
939
|
+
});
|
|
940
|
+
realtime.install(bus); // OrderShipped → bus.emit('OrderShipped', payload)
|
|
941
|
+
// realtime.teardown(); // on unmount / route change
|
|
942
|
+
```
|
|
943
|
+
|
|
884
944
|
## HTTP Client
|
|
885
945
|
|
|
886
946
|
`postCommand` is exposed for use outside the transport plugin when you need direct HTTP control:
|
|
@@ -980,7 +1040,7 @@ const result = await bus.dispatch('userFetch', { id: 123 });
|
|
|
980
1040
|
|
|
981
1041
|
### useCommand
|
|
982
1042
|
|
|
983
|
-
|
|
1043
|
+
The single command composable — reactive `loading`/`lastError` signals plus `register()`, `on()`, and `emit()` with automatic cleanup. It uses no `getCurrentInstance()`, so it is Vapor-safe: the same API works in `<script setup vapor>` and VDOM components alike.
|
|
984
1044
|
|
|
985
1045
|
```vue
|
|
986
1046
|
<script setup vapor>
|
|
@@ -995,6 +1055,30 @@ const { dispatch, loading, lastError } = useCommand();
|
|
|
995
1055
|
</template>
|
|
996
1056
|
```
|
|
997
1057
|
|
|
1058
|
+
Need the full surface? `register()`, `on()`, `emit()`, and `dispose()` are part of the same composable:
|
|
1059
|
+
|
|
1060
|
+
```vue
|
|
1061
|
+
<script setup vapor>
|
|
1062
|
+
import { useCommand } from 'vapor-chamber';
|
|
1063
|
+
|
|
1064
|
+
const { dispatch, register, on, emit, loading, lastError, dispose } = useCommand();
|
|
1065
|
+
|
|
1066
|
+
// Register a handler scoped to this component
|
|
1067
|
+
register('cartAdd', (cmd) => addToCart(cmd.target));
|
|
1068
|
+
|
|
1069
|
+
// Listen to patterns
|
|
1070
|
+
on('cart*', (cmd, result) => console.log('Cart event:', cmd.action));
|
|
1071
|
+
|
|
1072
|
+
// Dispatch with reactive loading/error tracking
|
|
1073
|
+
const result = dispatch('cartAdd', product, { quantity: 1 });
|
|
1074
|
+
|
|
1075
|
+
// Emit a domain event (no handler required, no result)
|
|
1076
|
+
emit('cartChanged', { count: 1 });
|
|
1077
|
+
|
|
1078
|
+
// Auto-cleanup via onScopeDispose — or call dispose() manually
|
|
1079
|
+
</script>
|
|
1080
|
+
```
|
|
1081
|
+
|
|
998
1082
|
### defineVaporCommand
|
|
999
1083
|
|
|
1000
1084
|
Zero-overhead dispatch for hot paths — no reactive `loading`/`lastError` signals created.
|
|
@@ -1015,29 +1099,6 @@ dispatch({ event: 'page_view', params: { page: '/shop' } });
|
|
|
1015
1099
|
</script>
|
|
1016
1100
|
```
|
|
1017
1101
|
|
|
1018
|
-
### useVaporCommand
|
|
1019
|
-
|
|
1020
|
-
Full-featured composable for Vapor components — reactive `loading`/`lastError` signals plus `register()` and `on()` with automatic cleanup. Unlike `defineVaporCommand` (fire-and-forget), this tracks reactive state. Unlike `useCommand` (VDOM), this uses no `getCurrentInstance()` — safe in Vapor's scope-based lifecycle:
|
|
1021
|
-
|
|
1022
|
-
```vue
|
|
1023
|
-
<script setup vapor>
|
|
1024
|
-
import { useVaporCommand } from 'vapor-chamber';
|
|
1025
|
-
|
|
1026
|
-
const { dispatch, register, on, loading, lastError, dispose } = useVaporCommand();
|
|
1027
|
-
|
|
1028
|
-
// Register a handler scoped to this component
|
|
1029
|
-
register('cartAdd', (cmd) => addToCart(cmd.target));
|
|
1030
|
-
|
|
1031
|
-
// Listen to patterns
|
|
1032
|
-
on('cart*', (cmd, result) => console.log('Cart event:', cmd.action));
|
|
1033
|
-
|
|
1034
|
-
// Dispatch with reactive loading/error tracking
|
|
1035
|
-
const result = dispatch('cartAdd', product, { quantity: 1 });
|
|
1036
|
-
|
|
1037
|
-
// Auto-cleanup via onScopeDispose — or call dispose() manually
|
|
1038
|
-
</script>
|
|
1039
|
-
```
|
|
1040
|
-
|
|
1041
1102
|
### useCommandState
|
|
1042
1103
|
|
|
1043
1104
|
State managed by commands:
|
|
@@ -1271,16 +1332,25 @@ app.mount('#app');
|
|
|
1271
1332
|
|
|
1272
1333
|
## Examples
|
|
1273
1334
|
|
|
1274
|
-
See
|
|
1335
|
+
See [`examples/`](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples) — the [examples index](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples) lists all of them. **Runnable full-project apps:**
|
|
1336
|
+
|
|
1337
|
+
| App | What it shows |
|
|
1338
|
+
|-----|---------------|
|
|
1339
|
+
| [`vapor-sfc`](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples/vapor-sfc) | `<script setup vapor>` SFC tree — `useCommand` / `defineVaporCommand` / `useSharedCommandState` |
|
|
1340
|
+
| [`vapor-island-cart`](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples/vapor-island-cart) | Light-DOM Vapor custom-element islands coordinating through one bus |
|
|
1341
|
+
| [`exo-astro`](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples/exo-astro) | Declarative directives for Astro — dispatch *before* hydration |
|
|
1342
|
+
| [`laravel-app`](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples/laravel-app) | Verified Laravel 12: Blade + core IIFE + real CSRF (419/401) |
|
|
1343
|
+
|
|
1344
|
+
**Single-file snippets** (plus `feature-*` / `pattern-*` files — see the [index](https://github.com/lucianofedericopereira/vapor-chamber/tree/main/examples)):
|
|
1275
1345
|
|
|
1276
1346
|
| Example | Description |
|
|
1277
1347
|
|---------|-------------|
|
|
1278
|
-
| [`shopping-cart.ts`](
|
|
1279
|
-
| [`form-validation.ts`](
|
|
1280
|
-
| [`async-api.ts`](
|
|
1281
|
-
| [`realtime-search.ts`](
|
|
1282
|
-
| [`custom-plugins.ts`](
|
|
1283
|
-
| [`vue-vapor-component.vue`](
|
|
1348
|
+
| [`shopping-cart.ts`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/shopping-cart.ts) | Cart with validation, history, and undo/redo |
|
|
1349
|
+
| [`form-validation.ts`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/form-validation.ts) | Form validation with error handling |
|
|
1350
|
+
| [`async-api.ts`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/async-api.ts) | Async handlers with retry plugin |
|
|
1351
|
+
| [`realtime-search.ts`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/realtime-search.ts) | Debounced search queries |
|
|
1352
|
+
| [`custom-plugins.ts`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/custom-plugins.ts) | Analytics, auth guard, rate limiter plugins |
|
|
1353
|
+
| [`vue-vapor-component.vue`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/examples/vue-vapor-component.vue) | Full Vue Vapor todo app |
|
|
1284
1354
|
|
|
1285
1355
|
## API Reference
|
|
1286
1356
|
|
|
@@ -1332,9 +1402,8 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1332
1402
|
|
|
1333
1403
|
| Composable | Description |
|
|
1334
1404
|
|------------|-------------|
|
|
1335
|
-
| `useCommand()` |
|
|
1405
|
+
| `useCommand()` | Vapor-safe composable: dispatch + register/on/emit + reactive loading/error state (per-call signals), auto-cleanup on scope disposal |
|
|
1336
1406
|
| `useSharedCommandState(options?)` | Aggregate `isAnyLoading` + `errors` ring buffer, **shared** across every subscriber on the same bus. Use for toolbars, status bars, global spinners. Saves ~2 signal nodes per subscribing component. |
|
|
1337
|
-
| `useVaporCommand()` | Vapor-safe composable with dispatch, register, on, loading/error, auto-cleanup |
|
|
1338
1407
|
| `defineVaporCommand(action, handler, options?)` | Zero-overhead dispatch for hot paths |
|
|
1339
1408
|
| `useCommandState(initial, handlers)` | State managed by commands |
|
|
1340
1409
|
| `useCommandHistory(options?)` | Reactive undo/redo |
|
|
@@ -1409,6 +1478,8 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1409
1478
|
| `circuitBreaker` — per-action closed/open/half-open resilience | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1410
1479
|
| `rateLimit` — per-action sliding window limiter | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1411
1480
|
| `metrics` — lightweight telemetry (count, duration, errorRate) | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1481
|
+
| `serialize` — per-key sequential processing (async; prevents same-key races; `scope:'cross-tab'` via Web Locks) | `plugins-extra` | ✅ v1.5 | ✅ covered |
|
|
1482
|
+
| `idempotent` — collapse duplicate commands (double-submit/retry); stamps `Idempotency-Key` for the HTTP bridge | `plugins-extra` | ✅ v1.5 | ✅ covered |
|
|
1412
1483
|
|
|
1413
1484
|
### Utilities — optional, tree-shaken
|
|
1414
1485
|
|
|
@@ -1432,12 +1503,13 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1432
1503
|
| `createWsBridge` — WebSocket plugin + reconnect + bounded queue | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1433
1504
|
| `WsBridge.connected` — reactive signal for connection state | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1434
1505
|
| `createSseBridge` — server-push EventSource, accepts `BaseBus` | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1506
|
+
| `createEchoBridge` — Laravel Echo/Reverb realtime (public/private/presence → bus) | `transports` | ✅ v1.5.0 | ✅ covered |
|
|
1435
1507
|
|
|
1436
1508
|
### Vue composables — optional, requires Vue ≥3.5
|
|
1437
1509
|
|
|
1438
1510
|
| Feature | Module | Status | Tests |
|
|
1439
1511
|
|---------|--------|--------|-------|
|
|
1440
|
-
| `useCommand` — reactive loading/error | `chamber` | ✅ v0.1.0 | ✅
|
|
1512
|
+
| `useCommand` — reactive loading/error | `chamber` | ✅ v0.1.0 | ✅ ~95% coverage |
|
|
1441
1513
|
| `useCommandState` | `chamber` | ✅ v0.2.0 | ✅ covered |
|
|
1442
1514
|
| `useCommandHistory` — reactive undo/redo | `chamber` | ✅ v0.2.0 | ✅ covered |
|
|
1443
1515
|
| `useCommandGroup` — namespace isolation | `chamber` | ✅ v0.4.1 | ✅ covered |
|
|
@@ -1447,7 +1519,7 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1447
1519
|
| `onScopeDispose` lifecycle alignment | `chamber` | ✅ v0.4.0 | ✅ covered |
|
|
1448
1520
|
| `isVaporAvailable()` | `chamber` | ✅ v0.4.0 | ✅ covered |
|
|
1449
1521
|
| `createVaporChamberApp` / `getVaporInteropPlugin` / `defineVaporCommand` | `chamber-vapor` | ✅ v0.4.0 | ✅ covered |
|
|
1450
|
-
| `
|
|
1522
|
+
| `useCommand` — Vapor-safe reactive composable (register/on/emit/dispose) | `chamber` | ✅ v0.6.0 | ✅ covered |
|
|
1451
1523
|
| `tryAutoCleanup` dev warning (no scope/instance) | `chamber` | ✅ v0.6.0 | ✅ covered |
|
|
1452
1524
|
| `waitForVueDetection()` — async Vue probe | `chamber` | ✅ v0.6.0 | ✅ covered |
|
|
1453
1525
|
|
|
@@ -1506,12 +1578,12 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1506
1578
|
| `createCommandPool` — object pool for hot paths | ✅ Done (v1.0) |
|
|
1507
1579
|
| Recursion depth guard (max 10) | ✅ Done (v1.0) |
|
|
1508
1580
|
| Architectural whitepaper | ✅ Done (v0.6.0) |
|
|
1509
|
-
| `chamber.ts` branch coverage |
|
|
1581
|
+
| `chamber.ts` branch coverage | ✅ ~87% branch / ~95% stmts (target met) |
|
|
1510
1582
|
| Publish to npm as `vapor-chamber@1.0.0` | ⬜ Pending |
|
|
1511
1583
|
|
|
1512
1584
|
## Documentation
|
|
1513
1585
|
|
|
1514
|
-
See [`docs/whitepaper.md`](
|
|
1586
|
+
See [`docs/whitepaper.md`](https://github.com/lucianofedericopereira/vapor-chamber/blob/main/docs/whitepaper.md) for design philosophy, architecture, camelCase naming rationale, Vue 3.6 Vapor alignment, SSR guide, and migration strategy.
|
|
1515
1587
|
|
|
1516
1588
|
## Design Goals
|
|
1517
1589
|
|
package/ROADMAP.md
CHANGED
|
@@ -4,21 +4,45 @@ This project tracks Vue 3.6 while it is in beta. That has direct consequences
|
|
|
4
4
|
for what's stable, what's transitional, and what will change once Vue 3.6
|
|
5
5
|
ships stable. This file is the source of truth for that distinction.
|
|
6
6
|
|
|
7
|
-
Last reviewed against **Vue 3.6.0-beta.
|
|
7
|
+
Last reviewed against **Vue 3.6.0-beta.16** (2026-06-17).
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Posture: feature-complete; tracking Vue to stable
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
**The feature set is complete as of v1.5.0 and now locked.** v1.5.0 closed the last
|
|
14
|
+
planned capabilities — `serialize`, `idempotent`, `onMissing:'buffer'` deferred
|
|
15
|
+
dispatch, `createEchoBridge`, and the `vapor-chamber/reactive` companion — so the
|
|
16
|
+
command bus, plugins, transports, composables, schema/LLM layer, form bus, HTTP
|
|
17
|
+
client, testing utilities, and the Vapor surface are considered done. From here the
|
|
18
|
+
only forward motion until Vue 3.6 ships stable is:
|
|
19
|
+
|
|
20
|
+
1. **Tracking each new Vue 3.6 beta/RC** — verify the pass-through wrappers still
|
|
21
|
+
hold, fold any behavioral notes into the alignment table, bump the peer dep.
|
|
22
|
+
2. **The stable-landing realignment** (see "What flips at Vue 3.6 stable" below) —
|
|
23
|
+
wrapper elimination, registry collapse.
|
|
24
|
+
|
|
25
|
+
Maintenance work (correctness hardening, coverage, doc currency, perf re-measurement)
|
|
26
|
+
continues; new feature work does not. A genuinely new capability request is parked
|
|
27
|
+
until after 3.6 stable, when the deployment patterns that would justify it are
|
|
28
|
+
observable.
|
|
29
|
+
|
|
30
|
+
## Beta-territory specifics
|
|
31
|
+
|
|
32
|
+
- **Peer dependency:** `vue: ">=3.5.0 || >=3.6.0-beta.16"`. The lib supports
|
|
14
33
|
Vue 3.5 (composables only) and Vue 3.6 betas (full Vapor surface).
|
|
15
34
|
- **Vapor APIs are still moving.** `defineVaporCustomElement`, `defineVaporComponent`,
|
|
16
35
|
`defineVaporAsyncComponent` are stable in shape but their underlying behavior
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
keeps shifting. The APIs were introduced across **3.6.0-alpha.3–5**
|
|
37
|
+
(#13059 / #14017 / #13831), not beta.10; behavior has since moved with nearly
|
|
38
|
+
every beta (generics inference, emits/attrs split,
|
|
39
|
+
VDOM slots interop normalization, error recovery, TransitionGroup move hooks,
|
|
40
|
+
lazy lifecycle update jobs, HMR reload dedup, v-show move-hook suppression,
|
|
41
|
+
shared-definition hook retention, interop-bridge immutability). The lib's
|
|
42
|
+
wrappers are pass-through, so consumers inherit each beta's improvements without
|
|
43
|
+
code changes — but the wrappers themselves exist precisely because the API is
|
|
44
|
+
not yet final. See [the whitepaper's Vue 3.6 alignment table](./docs/whitepaper.md)
|
|
45
|
+
for the per-beta detail.
|
|
22
46
|
- **The lib's value during beta** is graceful degradation (`null` returns when
|
|
23
47
|
Vue's API is absent or not yet present), version probing (`isVaporAvailable`),
|
|
24
48
|
and a stable surface for consumers to code against while Vue itself iterates.
|
|
@@ -33,7 +57,9 @@ Vue 3.6 stable:
|
|
|
33
57
|
emit, meta, BusError, introspection.
|
|
34
58
|
- **Transports** — HTTP, WebSocket, SSE bridges. Independent of Vue.
|
|
35
59
|
- **Plugins** — logger, validator, history, debounce, throttle, authGuard,
|
|
36
|
-
optimistic, retry, persist, sync, cache, circuitBreaker, rateLimit, metrics
|
|
60
|
+
optimistic, retry, persist, sync, cache, circuitBreaker, rateLimit, metrics,
|
|
61
|
+
serialize (per-key sequential processing, async),
|
|
62
|
+
idempotent (collapse duplicate commands + stamp Idempotency-Key).
|
|
37
63
|
- **Schema / LLM layer** — bus → tool-call adapters for Anthropic / OpenAI.
|
|
38
64
|
- **Form bus** — reactive form state with async validation.
|
|
39
65
|
- **HTTP client** — fetch wrapper with CSRF, interceptors, dedup.
|
|
@@ -48,17 +74,20 @@ Vue 3.6 stable:
|
|
|
48
74
|
Everything below exists primarily to bridge the 3.5→3.6 gap. None will be
|
|
49
75
|
removed silently — each gets a deprecation cycle with a working escape hatch.
|
|
50
76
|
|
|
51
|
-
### `useVaporCommand` and `useCommand`
|
|
77
|
+
### `useVaporCommand` and `useCommand` have converged — **DONE**
|
|
52
78
|
|
|
53
|
-
The split
|
|
54
|
-
in Vapor components.
|
|
55
|
-
|
|
79
|
+
The split existed because pre-3.6, `getCurrentInstance()`-based cleanup fails
|
|
80
|
+
in Vapor components. `useCommand` now uses `onScopeDispose`-only cleanup and
|
|
81
|
+
no `getCurrentInstance()`, so it is Vapor-safe on its own.
|
|
56
82
|
|
|
57
|
-
**
|
|
58
|
-
composable
|
|
59
|
-
|
|
83
|
+
**Done:** `useVaporCommand` was folded into `useCommand`. There is now a single
|
|
84
|
+
command composable — `register`/`on`/`emit`/`dispose` plus reactive
|
|
85
|
+
`loading`/`lastError`, Vapor-safe in `<script setup vapor>` and VDOM alike.
|
|
86
|
+
`useVaporCommand` was **removed entirely** — not left as a deprecated alias.
|
|
87
|
+
The project tracks pre-release Vue with a tiny userbase, so the clean removal
|
|
88
|
+
was preferred over a deprecation cycle.
|
|
60
89
|
|
|
61
|
-
**
|
|
90
|
+
**Removed:** ~60 lines of duplicated logic, plus the "which one do I use?"
|
|
62
91
|
question from the docs.
|
|
63
92
|
|
|
64
93
|
### Thin Vapor wrappers will become opt-in via build flag
|
|
@@ -187,8 +216,79 @@ benchmark numbers, and decision tree.
|
|
|
187
216
|
| Version | Trigger | Headline |
|
|
188
217
|
|---------|----------------------------------|--------------------------------------------------------------------------|
|
|
189
218
|
| v1.2.x | Vue 3.6.0-beta.11+ | Beta-aligned: docs, build pipeline, IIFE split, regression tests, V8-aligned hot path, listener bucketing, persist coalescing |
|
|
190
|
-
| v1.3.0 |
|
|
191
|
-
|
|
|
219
|
+
| v1.3.0 | Vue 3.6.0-beta.12 | SSR/Hydration alignment, AbortController extensions (request/respond, dispatchBatch, child signals, WS/SSE bridge), useSharedCommandState, TestBus snapshot/time-travel |
|
|
220
|
+
| v1.4.0 | Vue 3.6.0-beta.13 | TransitionGroup fixes, interop scope IDs, SSR hydration fixes, lazy lifecycle jobs, signal.ts plain-object fallback, alien-signals class adapter, alien-signals promoted to dep |
|
|
221
|
+
| v1.5.0 | Vue 3.6.0-beta.14 | Beta.14 alignment (HMR reload dedup, v-show move-hook suppression, custom-element/interop fixes); `signal()` → `shallowRef` (skips deep-Proxy on object/array state); `serialize` plugin (per-key sequential, + cross-tab via Web Locks); `vapor-chamber/reactive` deep-reactivity companion; `onMissing:'buffer'` deferred dispatch (buffer-until-registered, for lazy/island hydration); `idempotent` plugin + HTTP `Idempotency-Key` forwarding (client+wire exactly-once). **Feature set locked here.** |
|
|
222
|
+
| v1.6.x | Each subsequent 3.6 beta / RC | **Tracking only** — alignment notes folded into the version table, peer-dep bump, perf re-measure. (beta.16 broke this expectation: it carried a breaking consolidation, so it landed as the v1.7.0 minor instead of a 1.6.x patch.) |
|
|
223
|
+
| v1.7.0 | Vue 3.6.0-beta.16 | **First post-lock delivery (unreleased).** Beta.16 alignment; `v-vc:command` event modifiers; **breaking: `useVaporCommand` removed → `useCommand` is the single composable** (the v2.0 merge, *delivered early* — it never depended on the stable identity call); dispatch core to 100% line+branch+func coverage + lazy buffer allocation; honest size/coverage/perf docs. Ships as a **minor** under the beta-window version policy below. |
|
|
224
|
+
| v2.0.0 | One minor cycle after 3.6 stable | Stable-landing realignment: `vue36` flavor wrapper elimination + registry collapse; remove wrappers' null path; finalize the identity decision. The `useVaporCommand`→`useCommand` merge is already **done** (shipped early in **v1.7.0** — see below). See checklist below. |
|
|
225
|
+
|
|
226
|
+
**Version policy during the beta window.** While Vue 3.6 is still beta, breaking
|
|
227
|
+
changes ship as **minors**, not majors — the peer dep is a moving beta and there is
|
|
228
|
+
effectively no userspace to protect, so a deprecation cycle would cost more than it
|
|
229
|
+
saves. **2.0.0 is reserved for the post-stable identity decision** (Vapor-first vs
|
|
230
|
+
bus-first; the `vue36` flavor + registry collapse), keeping the major bump meaningful.
|
|
231
|
+
Corollary — **we deliver first**: any v2.0-roadmapped item that does *not* depend on
|
|
232
|
+
the stable identity call ships early in a minor as soon as it's ready (the
|
|
233
|
+
`useVaporCommand`→`useCommand` merge landed this way in v1.7.0).
|
|
234
|
+
|
|
235
|
+
Note: the `vue36` build-flag wrapper elimination was once tentatively slated for
|
|
236
|
+
v1.5.0 — it is **blocked on Vue 3.6 RC/stable** (the dead-code branch only pays
|
|
237
|
+
off once consumers have a non-beta Vue in their tree), so it lands at v2.0.0, not
|
|
238
|
+
during beta. `createEchoBridge` (protocol-aware Reverb/Echo realtime — public /
|
|
239
|
+
private / presence channels → bus) **shipped in v1.5.0** (it's a receive-only
|
|
240
|
+
transport adapter, fully decoupled from Vue, so it wasn't blocked); see
|
|
241
|
+
[docs/integrations/laravel.md](./docs/integrations/laravel.md).
|
|
242
|
+
|
|
243
|
+
## Vue version-support matrix
|
|
244
|
+
|
|
245
|
+
Which Vue versions each released lib line supports. The peer dep is permissive
|
|
246
|
+
(`>=3.5.0 || >=3.6.0-beta.16`); this table is the *tested* support statement.
|
|
247
|
+
|
|
248
|
+
| vapor-chamber | Vue 3.5 (composables only) | Vue 3.6 beta | Notes |
|
|
249
|
+
|---------------|----------------------------|--------------|-------|
|
|
250
|
+
| v1.2.x | ✅ | beta.11+ | first beta-aligned line |
|
|
251
|
+
| v1.3.0 | ✅ | beta.12 | |
|
|
252
|
+
| v1.4.0 | ✅ | beta.13 | |
|
|
253
|
+
| v1.5.x | ✅ | beta.14 | feature-locked |
|
|
254
|
+
| **v1.6.x** | ✅ | **beta.15 → beta.16** | current; tracking-only bumps |
|
|
255
|
+
| v2.0.0 | ✅ (composables) | **3.6 stable** | `vue36` flavor adds zero-overhead path |
|
|
256
|
+
|
|
257
|
+
On Vue 3.5 you get the framework-agnostic surface (bus, plugins, transports,
|
|
258
|
+
composables with `onScopeDispose` cleanup). The full Vapor surface
|
|
259
|
+
(`defineVapor*`, `createVaporChamberApp`, interop plugin) requires Vue 3.6 and
|
|
260
|
+
returns `null` / throws with a clear message when Vapor is absent.
|
|
261
|
+
|
|
262
|
+
## What flips at Vue 3.6 stable
|
|
263
|
+
|
|
264
|
+
A single checklist for the stable landing (v2.0.0). Each item is detailed in
|
|
265
|
+
"What is transitional" above; this is the operational summary so the bump is
|
|
266
|
+
mechanical, not archaeological:
|
|
267
|
+
|
|
268
|
+
- [ ] **Peer dep** — add `^3.6.0` (stable) to the supported range.
|
|
269
|
+
- [ ] **`vue36` build flavor** — ship the second build with `__VAPOR_NATIVE__ = true`;
|
|
270
|
+
wrapper bodies inline to identity, the `chamber.ts` feature-detection
|
|
271
|
+
registry (`getDefineVaporComponentFn`, `_vueOnScopeDispose`, …) tree-shakes
|
|
272
|
+
to zero. Add the `vue36` conditional export.
|
|
273
|
+
- [x] **`useVaporCommand` → `useCommand`** — **done** (shipped early in v1.7.0, ahead of v2.0). The
|
|
274
|
+
two composables were folded into a single Vapor-safe `useCommand`
|
|
275
|
+
(`onScopeDispose`-only cleanup, `register`/`on`/`emit`/`dispose`).
|
|
276
|
+
`useVaporCommand` was removed clean — no deprecated re-export.
|
|
277
|
+
- [ ] **`createVaporChamberApp`** — soft-deprecate (`@deprecated` JSDoc), point at
|
|
278
|
+
`import { createVaporApp } from 'vue'`.
|
|
279
|
+
- [ ] **Typed Vapor surface** — once Vue's Vapor types settle at stable, give the
|
|
280
|
+
`defineVapor*` wrappers first-class inference using Vue's exported types
|
|
281
|
+
(`DefineVaporComponent`, `VaporComponent`, `VaporPublicProps`) via an isolated
|
|
282
|
+
`vapor-chamber/vapor` subpath export, so the `vue` type dependency never touches
|
|
283
|
+
the Vue-less main barrel. Until then the wrappers keep the opt-in `<T = any>`
|
|
284
|
+
generic added in v1.6.0 (no Vue-type dependency).
|
|
285
|
+
- [ ] **plugin-vue 6.x** — test, then bump the optional peer-dep range.
|
|
286
|
+
- [ ] **Re-measure** IIFE sizes (Rolldown/Vite 8 may shift them) and update README.
|
|
287
|
+
- [ ] **Variant contents** become semver-stable (the beta-era reshuffle freedom ends).
|
|
288
|
+
|
|
289
|
+
None of these is a behavior change for consumers who use the documented API —
|
|
290
|
+
they're internal collapses that the deprecation cycle (landing first in a v1.x
|
|
291
|
+
minor) makes safe.
|
|
192
292
|
|
|
193
293
|
## Vite + plugin-vue alignment
|
|
194
294
|
|
package/dist/alien-signals.d.ts
CHANGED
|
@@ -46,21 +46,6 @@ export type AlienSignalFn = <T>(initial?: T) => {
|
|
|
46
46
|
/** Read */ (): T;
|
|
47
47
|
/** Write */ (next: T): T;
|
|
48
48
|
};
|
|
49
|
-
/**
|
|
50
|
-
* Build a `CreateSignal` adapter from alien-signals' `signal` function.
|
|
51
|
-
* The returned function is what `configureSignal()` expects — it produces
|
|
52
|
-
* vapor-chamber-style `{ value }` objects backed by an alien-signal.
|
|
53
|
-
*
|
|
54
|
-
* Use this when you want manual control. For the typical case, prefer
|
|
55
|
-
* {@link configureAlienSignals} which installs the adapter directly.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* import { signal as alienSignal } from 'alien-signals';
|
|
59
|
-
* import { configureSignal } from 'vapor-chamber';
|
|
60
|
-
* import { alienSignalAdapter } from 'vapor-chamber/alien-signals';
|
|
61
|
-
*
|
|
62
|
-
* configureSignal(alienSignalAdapter(alienSignal));
|
|
63
|
-
*/
|
|
64
49
|
export declare function alienSignalAdapter(alienSignal: AlienSignalFn): CreateSignal;
|
|
65
50
|
/**
|
|
66
51
|
* Install alien-signals as the underlying reactive primitive for every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alien-signals.d.ts","sourceRoot":"","sources":["../src/alien-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK;IAC9C,WAAW,CAAC,IAAI,CAAC,CAAC;IAClB,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"alien-signals.d.ts","sourceRoot":"","sources":["../src/alien-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK;IAC9C,WAAW,CAAC,IAAI,CAAC,CAAC;IAClB,YAAY,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;CAC3B,CAAC;AAyBF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,aAAa,GAAG,YAAY,CAE3E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,aAAa,GAAG,IAAI,CAEtE"}
|