vapor-chamber 0.5.0 → 1.0.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 +322 -14
- package/dist/chamber-vapor.d.ts +26 -2
- package/dist/chamber-vapor.d.ts.map +1 -1
- package/dist/chamber-vapor.js +52 -2
- package/dist/chamber.d.ts +10 -0
- package/dist/chamber.d.ts.map +1 -1
- package/dist/chamber.js +68 -26
- package/dist/command-bus.d.ts +283 -11
- package/dist/command-bus.d.ts.map +1 -1
- package/dist/command-bus.js +549 -61
- package/dist/directives.d.ts.map +1 -1
- package/dist/directives.js +45 -12
- package/dist/form.d.ts +11 -0
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +36 -11
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +18 -9
- package/dist/index.d.ts +20 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -7
- package/dist/plugins-core.d.ts +61 -3
- package/dist/plugins-core.d.ts.map +1 -1
- package/dist/plugins-core.js +112 -6
- package/dist/plugins-extra.d.ts +116 -0
- package/dist/plugins-extra.d.ts.map +1 -0
- package/dist/plugins-extra.js +275 -0
- package/dist/plugins.d.ts +2 -2
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +2 -2
- package/dist/schema.d.ts +91 -13
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +177 -44
- package/dist/testing.d.ts +10 -2
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +118 -18
- package/dist/transports.d.ts +16 -0
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +30 -6
- package/dist/utilities.d.ts +100 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +119 -0
- package/dist/vapor-chamber.iife.js +510 -83
- package/dist/vapor-chamber.iife.js.map +4 -4
- package/dist/vapor-chamber.iife.min.js +2 -2
- package/dist/vite-hmr.d.ts.map +1 -1
- package/dist/vite-hmr.js +3 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -120,7 +120,7 @@ vapor-chamber is built in layers. The **core** is framework-agnostic, has zero d
|
|
|
120
120
|
form.ts · schema.ts · devtools.ts · directives.ts · vite-hmr.ts
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
-
### Coverage & stability at
|
|
123
|
+
### Coverage & stability at v1.0
|
|
124
124
|
|
|
125
125
|
| Layer | Module | Coverage | Status |
|
|
126
126
|
|-------|--------|----------|--------|
|
|
@@ -133,10 +133,10 @@ vapor-chamber is built in layers. The **core** is framework-agnostic, has zero d
|
|
|
133
133
|
| Vue | `chamber.ts` | 76% | ✅ Stable |
|
|
134
134
|
| Extras | `form.ts` | 99% | ✅ Stable |
|
|
135
135
|
| Extras | `schema.ts` | 92% | ✅ Stable |
|
|
136
|
-
| Vue 3.6 | `chamber-vapor.ts` |
|
|
137
|
-
| Vue | `directives.ts` |
|
|
138
|
-
| Build | `devtools.ts` |
|
|
139
|
-
| Build | `vite-hmr.ts` |
|
|
136
|
+
| Vue 3.6 | `chamber-vapor.ts` | ✅ | ✅ Stable (unit-tested without Vue 3.6 runtime) |
|
|
137
|
+
| Vue | `directives.ts` | ✅ | ✅ Stable (unit-tested with DOM stubs) |
|
|
138
|
+
| Build | `devtools.ts` | ✅ | ✅ Stable (unit-tested with mock DevTools API) |
|
|
139
|
+
| Build | `vite-hmr.ts` | ✅ | ✅ Stable (unit-tested without Vite runtime) |
|
|
140
140
|
| Build | `iife.ts` | — | 🔧 Bundle entry, not a public API |
|
|
141
141
|
|
|
142
142
|
Sub-path exports avoid pulling in optional modules:
|
|
@@ -188,7 +188,7 @@ if (result.ok) {
|
|
|
188
188
|
|
|
189
189
|
## Vue 3.6 Vapor Mode
|
|
190
190
|
|
|
191
|
-
Vapor Chamber
|
|
191
|
+
Vapor Chamber v1.0 is aligned with Vue 3.6 beta. It works in three contexts:
|
|
192
192
|
|
|
193
193
|
### 1. Pure Vapor App (smallest bundle)
|
|
194
194
|
|
|
@@ -366,6 +366,144 @@ bus.offAll('cart*');
|
|
|
366
366
|
bus.offAll();
|
|
367
367
|
```
|
|
368
368
|
|
|
369
|
+
### Query (Read-Only Dispatch)
|
|
370
|
+
|
|
371
|
+
`query()` is like `dispatch()` but skips `onBefore` hooks — reads don't trigger mutation gates (auth checks, loading spinners, optimistic updates). Plugins and `onAfter` hooks still fire:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
// Register a handler that reads data
|
|
375
|
+
bus.register('getUser', (cmd) => db.users.find(cmd.target.id));
|
|
376
|
+
|
|
377
|
+
// Read-only — beforeHooks skipped, handler + plugins + afterHooks fire
|
|
378
|
+
const result = bus.query('getUser', { id: 42 });
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
This is the CQRS separation: `dispatch()` for commands (writes), `query()` for queries (reads).
|
|
382
|
+
|
|
383
|
+
### Domain Events (emit)
|
|
384
|
+
|
|
385
|
+
Fire an event that notifies `on()` listeners without requiring a handler and without returning a result. Use for observations (not commands):
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
// Listen to domain events
|
|
389
|
+
bus.on('orderCreated', (cmd) => analytics.track('order', cmd.target));
|
|
390
|
+
bus.on('order*', (cmd) => audit.log(cmd.action, cmd.target));
|
|
391
|
+
|
|
392
|
+
// Fire — no handler needed, no result
|
|
393
|
+
bus.emit('orderCreated', { orderId: 42, total: 99.50 });
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Command Metadata
|
|
397
|
+
|
|
398
|
+
Every dispatched command is auto-stamped with `meta`:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
bus.onAfter((cmd) => {
|
|
402
|
+
console.log(cmd.meta.id); // unique UUID per dispatch
|
|
403
|
+
console.log(cmd.meta.ts); // Date.now() timestamp
|
|
404
|
+
console.log(cmd.meta.correlationId); // trace ID for command chains
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Propagate tracing through payload
|
|
408
|
+
bus.dispatch('orderShip', order, {
|
|
409
|
+
__correlationId: originalCommand.meta.id,
|
|
410
|
+
__causationId: originalCommand.meta.id,
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Structured Errors (BusError)
|
|
415
|
+
|
|
416
|
+
Every error in vapor-chamber has a machine-readable code, severity, and emitter:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { BusError } from 'vapor-chamber';
|
|
420
|
+
|
|
421
|
+
const result = bus.dispatch('missing', {});
|
|
422
|
+
if (!result.ok && result.error instanceof BusError) {
|
|
423
|
+
result.error.code; // 'VC_CORE_NO_HANDLER'
|
|
424
|
+
result.error.severity; // 'error'
|
|
425
|
+
result.error.emitter; // 'core'
|
|
426
|
+
result.error.action; // 'missing'
|
|
427
|
+
result.error.context; // { } — extra data (e.g. retryIn for throttle)
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
All codes: `VC_CORE_NO_HANDLER`, `VC_CORE_THROTTLED`, `VC_CORE_REQUEST_TIMEOUT`, `VC_PLUGIN_CIRCUIT_OPEN`, `VC_PLUGIN_RATE_LIMITED`, etc. Use `ERROR_CODE_REGISTRY` for a complete lookup table with fix suggestions.
|
|
432
|
+
|
|
433
|
+
### Bus Introspection
|
|
434
|
+
|
|
435
|
+
`inspectBus()` returns a full topology snapshot — useful for DevTools, debugging, and test assertions:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import { inspectBus } from 'vapor-chamber';
|
|
439
|
+
|
|
440
|
+
const info = inspectBus(bus);
|
|
441
|
+
info.actions; // ['cartAdd', 'cartRemove', ...]
|
|
442
|
+
info.undoActions; // ['cartAdd'] — actions with registered undo handlers
|
|
443
|
+
info.pluginCount; // 3
|
|
444
|
+
info.pluginPriorities; // [10, 5, 0]
|
|
445
|
+
info.sealed; // false
|
|
446
|
+
info.dispatchDepth; // 0 (increments during nested dispatch)
|
|
447
|
+
info.activeTimers; // 0 (throttle timers currently running)
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Tree-shakeable — not included in your bundle unless imported. Also available on TestBus: `bus.inspect()`.
|
|
451
|
+
|
|
452
|
+
### Utilities
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
import { createChamber, createWorkflow, createReaction } from 'vapor-chamber';
|
|
456
|
+
|
|
457
|
+
// Group handlers under a namespace
|
|
458
|
+
const cart = createChamber('cart', { add: handleAdd, remove: handleRemove });
|
|
459
|
+
cart.install(bus); // Registers: cartAdd, cartRemove
|
|
460
|
+
|
|
461
|
+
// Saga: sequential steps with automatic compensation
|
|
462
|
+
const checkout = createWorkflow([
|
|
463
|
+
{ action: 'cartValidate' },
|
|
464
|
+
{ action: 'paymentReserve', compensate: 'paymentRelease' },
|
|
465
|
+
{ action: 'orderCreate', compensate: 'orderCancel' },
|
|
466
|
+
]);
|
|
467
|
+
const result = await checkout.run(bus, { cartId }); // compensates on failure
|
|
468
|
+
|
|
469
|
+
// Declarative cross-domain reaction
|
|
470
|
+
createReaction('cartAdd', 'inventoryCheck', {
|
|
471
|
+
when: (cmd, result) => result.ok,
|
|
472
|
+
map: (cmd) => ({ itemId: cmd.payload.itemId }),
|
|
473
|
+
}).install(bus);
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Extra Plugins
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
import { cache, circuitBreaker, rateLimit, metrics } from 'vapor-chamber';
|
|
480
|
+
|
|
481
|
+
bus.use(cache({ ttl: 60_000, actions: ['getUser*'] }));
|
|
482
|
+
bus.use(circuitBreaker({ threshold: 5, resetTimeout: 30_000 }));
|
|
483
|
+
bus.use(rateLimit({ max: 10, window: 1000 }));
|
|
484
|
+
|
|
485
|
+
const m = metrics();
|
|
486
|
+
bus.use(m);
|
|
487
|
+
console.log(m.summary()); // { cartAdd: { count: 42, avgMs: 1.2, errorRate: 0.02 } }
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### LLM Integration Schemas
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
import { ERROR_CODE_REGISTRY, describeErrorCodes, busApiSchema } from 'vapor-chamber';
|
|
494
|
+
|
|
495
|
+
// Include in system prompt so LLMs know all error codes and fixes
|
|
496
|
+
const errorTable = describeErrorCodes();
|
|
497
|
+
|
|
498
|
+
// Include bus API schema so LLMs don't hallucinate methods
|
|
499
|
+
const apiSchema = busApiSchema();
|
|
500
|
+
|
|
501
|
+
// Lookup a specific error code
|
|
502
|
+
import { getErrorEntry } from 'vapor-chamber';
|
|
503
|
+
const entry = getErrorEntry('VC_CORE_NO_HANDLER');
|
|
504
|
+
console.log(entry?.fix); // "Register a handler with bus.register(action, handler)"
|
|
505
|
+
```
|
|
506
|
+
|
|
369
507
|
### Request / Response
|
|
370
508
|
|
|
371
509
|
Async request/response pattern with timeout:
|
|
@@ -394,6 +532,7 @@ Falls back to normal `dispatch()` if no responder is registered.
|
|
|
394
532
|
| `throttle(actions, wait)` | Limit execution frequency |
|
|
395
533
|
| `authGuard(options)` | Block protected commands when unauthenticated |
|
|
396
534
|
| `optimistic(handlers)` | Apply optimistic updates, rollback on failure |
|
|
535
|
+
| `optimisticUndo(bus, actions, opts?)` | Auto-rollback via registered undo handlers |
|
|
397
536
|
| `retry(options)` | Retry failed async dispatches with backoff |
|
|
398
537
|
| `persist(options)` | Auto-save state to localStorage after commands |
|
|
399
538
|
| `sync(options, bus?)` | Broadcast commands across browser tabs |
|
|
@@ -471,6 +610,30 @@ bus.use(optimistic({
|
|
|
471
610
|
}));
|
|
472
611
|
```
|
|
473
612
|
|
|
613
|
+
### optimisticUndo
|
|
614
|
+
|
|
615
|
+
Automatic rollback using registered undo handlers. When a dispatch fails, executes the undo handler registered via `register(action, handler, { undo })`. Works on both sync and async buses:
|
|
616
|
+
|
|
617
|
+
```typescript
|
|
618
|
+
import { createAsyncCommandBus, optimisticUndo } from 'vapor-chamber';
|
|
619
|
+
|
|
620
|
+
const bus = createAsyncCommandBus();
|
|
621
|
+
|
|
622
|
+
// Register handler with undo
|
|
623
|
+
bus.register('cartAdd', async (cmd) => {
|
|
624
|
+
return await api.addToCart(cmd.target);
|
|
625
|
+
}, {
|
|
626
|
+
undo: (cmd) => api.removeFromCart(cmd.target.id),
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
// Install optimisticUndo — auto-rollback on failure
|
|
630
|
+
bus.use(optimisticUndo(bus, ['cartAdd'], {
|
|
631
|
+
predict: (cmd) => ({ ...cart, items: [...cart.items, cmd.target] }),
|
|
632
|
+
onRollback: (cmd, error) => toast.error(`Rolled back: ${error.message}`),
|
|
633
|
+
onRollbackError: (cmd, undoErr, origErr) => console.error('Undo failed:', undoErr),
|
|
634
|
+
}));
|
|
635
|
+
```
|
|
636
|
+
|
|
474
637
|
### retry
|
|
475
638
|
|
|
476
639
|
Async plugin that retries failed dispatches with configurable backoff. Install on an `AsyncCommandBus`:
|
|
@@ -569,6 +732,19 @@ const result = await bus.dispatch('orderCreate', { items: cart });
|
|
|
569
732
|
// → POST /api/commands { command: 'orderCreate', target: { items: ... } }
|
|
570
733
|
```
|
|
571
734
|
|
|
735
|
+
**Vapor lifecycle integration** — cancel in-flight requests when a component is disposed:
|
|
736
|
+
|
|
737
|
+
```typescript
|
|
738
|
+
// In <script setup vapor>:
|
|
739
|
+
const ctrl = new AbortController();
|
|
740
|
+
onScopeDispose(() => ctrl.abort());
|
|
741
|
+
|
|
742
|
+
bus.use(createHttpBridge({
|
|
743
|
+
endpoint: '/api/vc',
|
|
744
|
+
scopeController: ctrl, // all requests cancelled on scope disposal
|
|
745
|
+
}));
|
|
746
|
+
```
|
|
747
|
+
|
|
572
748
|
The backend response shape:
|
|
573
749
|
```json
|
|
574
750
|
{ "state": { "orderId": 42, "status": "pending" } }
|
|
@@ -594,8 +770,18 @@ bus.use(ws);
|
|
|
594
770
|
ws.connect();
|
|
595
771
|
|
|
596
772
|
// Lifecycle
|
|
597
|
-
ws.isConnected();
|
|
598
|
-
ws.
|
|
773
|
+
ws.isConnected(); // → boolean (imperative check)
|
|
774
|
+
ws.connected.value; // → boolean (reactive signal — bindable in templates)
|
|
775
|
+
ws.disconnect(); // intentional close — suppresses reconnect
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
The `connected` signal is reactive — bind it directly in Vapor or VDOM templates without polling:
|
|
779
|
+
|
|
780
|
+
```vue
|
|
781
|
+
<template>
|
|
782
|
+
<span v-if="ws.connected.value">🟢 Connected</span>
|
|
783
|
+
<span v-else>🔴 Disconnected</span>
|
|
784
|
+
</template>
|
|
599
785
|
```
|
|
600
786
|
|
|
601
787
|
### createSseBridge
|
|
@@ -656,6 +842,27 @@ console.log(`${result.successCount} of ${result.results.length} succeeded`);
|
|
|
656
842
|
// result.results — all CommandResult objects, in order
|
|
657
843
|
```
|
|
658
844
|
|
|
845
|
+
### Transactional Batch
|
|
846
|
+
|
|
847
|
+
Use `transactional: true` for all-or-nothing batch execution. If any command fails, all previously successful commands are rolled back using their registered undo handlers:
|
|
848
|
+
|
|
849
|
+
```typescript
|
|
850
|
+
bus.register('inventoryReserve', reserveHandler, { undo: releaseHandler });
|
|
851
|
+
bus.register('paymentCharge', chargeHandler, { undo: refundHandler });
|
|
852
|
+
bus.register('orderCreate', createHandler, { undo: cancelHandler });
|
|
853
|
+
|
|
854
|
+
const result = bus.dispatchBatch([
|
|
855
|
+
{ action: 'inventoryReserve', target: item },
|
|
856
|
+
{ action: 'paymentCharge', target: payment },
|
|
857
|
+
{ action: 'orderCreate', target: order },
|
|
858
|
+
], { transactional: true });
|
|
859
|
+
|
|
860
|
+
if (!result.ok) {
|
|
861
|
+
// paymentCharge failed → inventoryReserve was rolled back
|
|
862
|
+
console.log('Rollbacks:', result.rollbacks); // compensation results
|
|
863
|
+
}
|
|
864
|
+
```
|
|
865
|
+
|
|
659
866
|
## Dead Letter Handling
|
|
660
867
|
|
|
661
868
|
Configure what happens when a command has no registered handler:
|
|
@@ -721,6 +928,29 @@ dispatch({ event: 'page_view', params: { page: '/shop' } });
|
|
|
721
928
|
</script>
|
|
722
929
|
```
|
|
723
930
|
|
|
931
|
+
### useVaporCommand
|
|
932
|
+
|
|
933
|
+
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:
|
|
934
|
+
|
|
935
|
+
```vue
|
|
936
|
+
<script setup vapor>
|
|
937
|
+
import { useVaporCommand } from 'vapor-chamber';
|
|
938
|
+
|
|
939
|
+
const { dispatch, register, on, loading, lastError, dispose } = useVaporCommand();
|
|
940
|
+
|
|
941
|
+
// Register a handler scoped to this component
|
|
942
|
+
register('cartAdd', (cmd) => addToCart(cmd.target));
|
|
943
|
+
|
|
944
|
+
// Listen to patterns
|
|
945
|
+
on('cart*', (cmd, result) => console.log('Cart event:', cmd.action));
|
|
946
|
+
|
|
947
|
+
// Dispatch with reactive loading/error tracking
|
|
948
|
+
const result = dispatch('cartAdd', product, { quantity: 1 });
|
|
949
|
+
|
|
950
|
+
// Auto-cleanup via onScopeDispose — or call dispose() manually
|
|
951
|
+
</script>
|
|
952
|
+
```
|
|
953
|
+
|
|
724
954
|
### useCommandState
|
|
725
955
|
|
|
726
956
|
State managed by commands:
|
|
@@ -837,6 +1067,18 @@ await form.submit(); // validate → onSubmit → returns bo
|
|
|
837
1067
|
form.reset(); // restore initial values
|
|
838
1068
|
```
|
|
839
1069
|
|
|
1070
|
+
**Headless mode** — skip reactive signal allocations for server-side, batch, or non-UI use:
|
|
1071
|
+
|
|
1072
|
+
```typescript
|
|
1073
|
+
const form = createFormBus({
|
|
1074
|
+
fields: { email: '', password: '' },
|
|
1075
|
+
rules: { email: (v) => v.includes('@') ? null : 'Invalid email' },
|
|
1076
|
+
onSubmit: async (values) => await api.login(values),
|
|
1077
|
+
reactive: false, // no Vue signals — plain get/set wrappers
|
|
1078
|
+
});
|
|
1079
|
+
// All APIs work identically — values, errors, isDirty, etc. are still readable
|
|
1080
|
+
```
|
|
1081
|
+
|
|
840
1082
|
Template usage (Vue 3):
|
|
841
1083
|
|
|
842
1084
|
```vue
|
|
@@ -962,6 +1204,10 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
962
1204
|
| `createCommandBus(options?)` | Create a synchronous command bus |
|
|
963
1205
|
| `createAsyncCommandBus(options?)` | Create an async command bus |
|
|
964
1206
|
| `createTestBus(options?)` | Create a test bus that records dispatches |
|
|
1207
|
+
| `inspectBus(bus)` | Returns `BusInspection` snapshot of bus topology (tree-shakeable) |
|
|
1208
|
+
| `unsealBus(bus)` | Unseal a sealed bus (tree-shakeable escape hatch) |
|
|
1209
|
+
| `createCommandPool(size)` | Pre-allocated Command object pool for hot paths |
|
|
1210
|
+
| `commandKey(action, target)` | Stable `action:target` string key for cache integration |
|
|
965
1211
|
|
|
966
1212
|
**`CommandBusOptions`**
|
|
967
1213
|
|
|
@@ -974,7 +1220,9 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
974
1220
|
|
|
975
1221
|
| Method | Description |
|
|
976
1222
|
|--------|-------------|
|
|
977
|
-
| `dispatch(action, target, payload?)` | Execute a command |
|
|
1223
|
+
| `dispatch(action, target, payload?)` | Execute a command (write). Auto-stamps `cmd.meta` |
|
|
1224
|
+
| `query(action, target, payload?)` | Read-only dispatch — skips `onBefore` hooks, runs plugins + handler + afterHooks |
|
|
1225
|
+
| `emit(event, data?)` | Fire a domain event — notifies `on()` listeners, no handler required |
|
|
978
1226
|
| `dispatchBatch(commands[], options?)` | Execute multiple commands. Returns `{ successCount, failCount, results }` |
|
|
979
1227
|
| `register(action, handler, options?)` | Register a handler. Options: `{ undo?, throttle? }` |
|
|
980
1228
|
| `use(plugin, options?)` | Add a plugin. `options.priority` controls order |
|
|
@@ -986,7 +1234,11 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
986
1234
|
| `request(action, target, payload?, options?)` | Async request/response with timeout (default 5s) |
|
|
987
1235
|
| `respond(action, handler)` | Register a responder for `request()` calls |
|
|
988
1236
|
| `hasHandler(action)` | Returns true if a handler is registered for the action |
|
|
1237
|
+
| `registeredActions()` | Returns `string[]` of all registered action names |
|
|
989
1238
|
| `clear()` | Remove all handlers, plugins, hooks, and listeners |
|
|
1239
|
+
| `seal()` | Freeze bus configuration — rejects register/use/clear after sealing |
|
|
1240
|
+
| `dispose()` | Clean teardown — clears state, cancels timers, marks bus as disposed |
|
|
1241
|
+
| `registeredActions()` | Returns `string[]` of all registered action names |
|
|
990
1242
|
| `getUndoHandler(action)` | Get the undo handler for an action (`@internal`) |
|
|
991
1243
|
|
|
992
1244
|
### Composables
|
|
@@ -994,6 +1246,7 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
994
1246
|
| Composable | Description |
|
|
995
1247
|
|------------|-------------|
|
|
996
1248
|
| `useCommand()` | Dispatch with reactive loading/error state |
|
|
1249
|
+
| `useVaporCommand()` | Vapor-safe composable with dispatch, register, on, loading/error, auto-cleanup |
|
|
997
1250
|
| `defineVaporCommand(action, handler, options?)` | Zero-overhead dispatch for hot paths |
|
|
998
1251
|
| `useCommandState(initial, handlers)` | State managed by commands |
|
|
999
1252
|
| `useCommandHistory(options?)` | Reactive undo/redo |
|
|
@@ -1031,7 +1284,19 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1031
1284
|
| `bus.hasHandler()` introspection | `command-bus` | ✅ v0.3.0 | ✅ covered |
|
|
1032
1285
|
| `bus.clear()` | `command-bus` | ✅ v0.5.0 | ✅ covered |
|
|
1033
1286
|
| `BaseBus` structural interface | `command-bus` | ✅ v0.6.0 | ✅ covered |
|
|
1287
|
+
| `query()` — CQRS read-only dispatch (skips beforeHooks) | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1288
|
+
| `emit()` — domain events (no handler, no result) | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1289
|
+
| `Command.meta` — auto-stamped id, ts, correlationId, causationId | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1290
|
+
| `registeredActions()` — introspection | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1034
1291
|
| `commandKey(action, target)` export | `command-bus` | ✅ v0.6.0 | ✅ covered |
|
|
1292
|
+
| `BusError` structured error class (code, severity, emitter) | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1293
|
+
| `inspectBus(bus)` — tree-shakeable topology introspection | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1294
|
+
| `bus.seal()` / `unsealBus(bus)` — freeze configuration | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1295
|
+
| `bus.dispose()` — clean teardown with timer cancellation | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1296
|
+
| `createCommandPool(size)` — pre-allocated object pool | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1297
|
+
| Transactional batch with undo rollback | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1298
|
+
| Recursion depth guard (max 10) | `command-bus` | ✅ v1.0 | ✅ covered |
|
|
1299
|
+
| V8 optimizations (monomorphic shapes, index loops, extracted try/catch) | `command-bus` | ✅ v1.0 | ✅ bench |
|
|
1035
1300
|
| SSR isolation (independent bus instances) | `command-bus` | ✅ v0.5.0 | ✅ covered |
|
|
1036
1301
|
| `createTestBus` record + assert | `testing` | ✅ v0.2.0 | ✅ 96% coverage |
|
|
1037
1302
|
| `createTestBus` snapshot & time-travel | `testing` | ✅ v0.4.3 | ✅ covered |
|
|
@@ -1048,9 +1313,22 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1048
1313
|
| `throttle` | `plugins-core` | ✅ v0.3.0 | ✅ covered |
|
|
1049
1314
|
| `authGuard` | `plugins-core` | ✅ v0.3.0 | ✅ covered |
|
|
1050
1315
|
| `optimistic` | `plugins-core` | ✅ v0.3.0 | ✅ covered |
|
|
1316
|
+
| `optimisticUndo` — auto-rollback via registered undo handlers | `plugins-core` | ✅ v1.0 | ✅ covered |
|
|
1051
1317
|
| `retry` with configurable backoff + glob filter | `plugins-io` | ✅ v0.4.2 | ✅ 88% coverage |
|
|
1052
1318
|
| `persist` (localStorage / custom storage) | `plugins-io` | ✅ v0.4.2 | ✅ covered |
|
|
1053
1319
|
| `sync` (BroadcastChannel cross-tab) | `plugins-io` | ✅ v0.4.2 | ✅ covered |
|
|
1320
|
+
| `cache` — LRU query result caching with TTL + glob filter | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1321
|
+
| `circuitBreaker` — per-action closed/open/half-open resilience | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1322
|
+
| `rateLimit` — per-action sliding window limiter | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1323
|
+
| `metrics` — lightweight telemetry (count, duration, errorRate) | `plugins-extra` | ✅ v1.0 | ✅ covered |
|
|
1324
|
+
|
|
1325
|
+
### Utilities — optional, tree-shaken
|
|
1326
|
+
|
|
1327
|
+
| Feature | Module | Status | Tests |
|
|
1328
|
+
|---------|--------|--------|-------|
|
|
1329
|
+
| `createChamber` — declarative namespace grouping | `utilities` | ✅ v1.0 | ✅ covered |
|
|
1330
|
+
| `createWorkflow` — saga pattern with compensation | `utilities` | ✅ v1.0 | ✅ covered |
|
|
1331
|
+
| `createReaction` — declarative cross-domain rules | `utilities` | ✅ v1.0 | ✅ covered |
|
|
1054
1332
|
|
|
1055
1333
|
### Transport layer — optional, fully implemented
|
|
1056
1334
|
|
|
@@ -1062,7 +1340,9 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1062
1340
|
| 419 vs 401 fix — CSRF expiry ≠ session expiry | `http` | ✅ v0.6.0 | ✅ covered |
|
|
1063
1341
|
| `createHttpBridge` — fetch plugin | `transports` | ✅ v0.4.2 | ✅ 91% coverage |
|
|
1064
1342
|
| `HttpBridgeOptions.noRetry` — per-action retry disable | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1343
|
+
| `HttpBridgeOptions.scopeController` — Vapor lifecycle abort | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1065
1344
|
| `createWsBridge` — WebSocket plugin + reconnect + bounded queue | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1345
|
+
| `WsBridge.connected` — reactive signal for connection state | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1066
1346
|
| `createSseBridge` — server-push EventSource, accepts `BaseBus` | `transports` | ✅ v0.6.0 | ✅ covered |
|
|
1067
1347
|
|
|
1068
1348
|
### Vue composables — optional, requires Vue ≥3.5
|
|
@@ -1078,18 +1358,26 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1078
1358
|
| Signal shim + `configureSignal` | `chamber` | ✅ v0.3.0 | ✅ covered |
|
|
1079
1359
|
| `onScopeDispose` lifecycle alignment | `chamber` | ✅ v0.4.0 | ✅ covered |
|
|
1080
1360
|
| `isVaporAvailable()` | `chamber` | ✅ v0.4.0 | ✅ covered |
|
|
1081
|
-
| `createVaporChamberApp` / `getVaporInteropPlugin` / `defineVaporCommand` | `chamber-vapor` | ✅ v0.4.0 |
|
|
1361
|
+
| `createVaporChamberApp` / `getVaporInteropPlugin` / `defineVaporCommand` | `chamber-vapor` | ✅ v0.4.0 | ✅ covered |
|
|
1362
|
+
| `useVaporCommand` — Vapor-safe reactive composable | `chamber-vapor` | ✅ v0.6.0 | ✅ covered |
|
|
1363
|
+
| `tryAutoCleanup` dev warning (no scope/instance) | `chamber` | ✅ v0.6.0 | ✅ covered |
|
|
1364
|
+
| `waitForVueDetection()` — async Vue probe | `chamber` | ✅ v0.6.0 | ✅ covered |
|
|
1082
1365
|
|
|
1083
1366
|
### Extras — optional, per-feature opt-in
|
|
1084
1367
|
|
|
1085
1368
|
| Feature | Module | Status | Tests |
|
|
1086
1369
|
|---------|--------|--------|-------|
|
|
1087
1370
|
| `createFormBus` — reactive form + sync/async validation | `form` | ✅ v0.6.0 | ✅ 99% coverage |
|
|
1371
|
+
| `FormBus` headless mode (`reactive: false`) | `form` | ✅ v0.6.0 | ✅ covered |
|
|
1088
1372
|
| Schema layer — `createSchemaCommandBus`, `toTools`, `synthesize` | `schema` | ✅ v0.5.0 | ✅ 92% coverage |
|
|
1373
|
+
| Schema auto-validation (`schemaValidator` auto-installed) | `schema` | ✅ v1.0 | ✅ covered |
|
|
1089
1374
|
| `SynthesizeOptions.adapter` — custom LLM adapter | `schema` | ✅ v0.6.0 | ✅ covered |
|
|
1090
|
-
| `
|
|
1091
|
-
| `
|
|
1092
|
-
|
|
|
1375
|
+
| `ERROR_CODE_REGISTRY` — structured error lookup table | `schema` | ✅ v1.0 | ✅ covered |
|
|
1376
|
+
| `busApiSchema()` — JSON schema of bus API for LLM prompts | `schema` | ✅ v1.0 | ✅ covered |
|
|
1377
|
+
| `describeErrorCodes()` — plain-text error table for LLM system prompts | `schema` | ✅ v1.0 | ✅ covered |
|
|
1378
|
+
| `setupDevtools` — Vue DevTools panel | `devtools` | ✅ v0.4.0 | ✅ covered |
|
|
1379
|
+
| `createDirectivePlugin` — `v-command` directive + Vapor compat warning | `directives` | ✅ v0.6.0 | ✅ covered |
|
|
1380
|
+
| Vite HMR plugin (+ `.vapor.vue` support) | `vite-hmr` | ✅ v0.6.0 | ✅ covered |
|
|
1093
1381
|
| IIFE / CDN bundle | `iife` | ✅ v0.5.0 | 🔧 bundle entry |
|
|
1094
1382
|
|
|
1095
1383
|
### v1.0 checklist
|
|
@@ -1097,18 +1385,38 @@ See the [`examples/`](./examples) folder for complete, runnable examples:
|
|
|
1097
1385
|
| Item | Status |
|
|
1098
1386
|
|------|--------|
|
|
1099
1387
|
| Core (`command-bus` + `testing`) at 90%+ coverage | ✅ Done |
|
|
1100
|
-
| All tests green (
|
|
1388
|
+
| All tests green (466/466, 0 failures) | ✅ Done |
|
|
1101
1389
|
| Optional modules clearly marked in exports | ✅ Done |
|
|
1102
1390
|
| Transport layer fully tested (HTTP + WS + SSE) | ✅ Done |
|
|
1103
1391
|
| Plugins fully tested | ✅ Done |
|
|
1104
1392
|
| camelCase naming convention locked in | ✅ Done |
|
|
1105
1393
|
| `onBefore` / `offAll` / `once` on both buses | ✅ Done (v0.6.0) |
|
|
1394
|
+
| `query()` — CQRS read-only dispatch | ✅ Done (v1.0) |
|
|
1395
|
+
| `emit()` — domain events (no handler required) | ✅ Done (v1.0) |
|
|
1396
|
+
| `Command.meta` — auto-stamped id, timestamp, tracing | ✅ Done (v1.0) |
|
|
1397
|
+
| `registeredActions()` — introspection | ✅ Done (v1.0) |
|
|
1398
|
+
| `TestBus.onBefore` fires for real | ✅ Done (v1.0) |
|
|
1106
1399
|
| `BaseBus` structural interface for cross-bus utilities | ✅ Done (v0.6.0) |
|
|
1400
|
+
| V8 engine optimizations (monomorphic shapes, no .slice() in hot paths) | ✅ Done (v1.0) |
|
|
1401
|
+
| `BusError` structured error class with codes, severity, emitter | ✅ Done (v1.0) |
|
|
1402
|
+
| `ERROR_CODE_REGISTRY` + `busApiSchema()` for LLM integration | ✅ Done (v1.0) |
|
|
1403
|
+
| `createChamber`, `createWorkflow`, `createReaction` utilities | ✅ Done (v1.0) |
|
|
1404
|
+
| `cache`, `circuitBreaker`, `rateLimit`, `metrics` plugins | ✅ Done (v1.0) |
|
|
1405
|
+
| LLM-friendly naming (`TargetOf`/`PayloadOf`/`ResultOf`) + `@example` JSDoc | ✅ Done (v1.0) |
|
|
1406
|
+
| Self-correcting error messages with fix suggestions | ✅ Done (v1.0) |
|
|
1107
1407
|
| CSRF / 419 / session-expiry correctness | ✅ Done (v0.6.0) |
|
|
1108
1408
|
| Form async validation | ✅ Done (v0.6.0) |
|
|
1109
1409
|
| `HttpError.code` structured error codes | ✅ Done (v0.6.0) |
|
|
1110
1410
|
| WS queue cap (`maxQueueSize`) | ✅ Done (v0.6.0) |
|
|
1111
1411
|
| `synthesize` LLM adapter (proxy / OpenAI support) | ✅ Done (v0.6.0) |
|
|
1412
|
+
| Transactional batch with undo rollback | ✅ Done (v1.0) |
|
|
1413
|
+
| `optimisticUndo` plugin — auto-rollback via undo handlers | ✅ Done (v1.0) |
|
|
1414
|
+
| Schema auto-validation (`schemaValidator` auto-installed) | ✅ Done (v1.0) |
|
|
1415
|
+
| `inspectBus()` — tree-shakeable bus topology introspection | ✅ Done (v1.0) |
|
|
1416
|
+
| `bus.seal()` / `unsealBus()` — freeze configuration | ✅ Done (v1.0) |
|
|
1417
|
+
| `bus.dispose()` — clean teardown | ✅ Done (v1.0) |
|
|
1418
|
+
| `createCommandPool` — object pool for hot paths | ✅ Done (v1.0) |
|
|
1419
|
+
| Recursion depth guard (max 10) | ✅ Done (v1.0) |
|
|
1112
1420
|
| Architectural whitepaper | ✅ Done (v0.6.0) |
|
|
1113
1421
|
| `chamber.ts` branch coverage | 🔄 76% → target 85% |
|
|
1114
1422
|
| Publish to npm as `vapor-chamber@1.0.0` | ⬜ Pending |
|
package/dist/chamber-vapor.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* vapor-chamber — Vue 3.6+ Vapor-specific API
|
|
3
3
|
*
|
|
4
|
-
* createVaporChamberApp, getVaporInteropPlugin, defineVaporCommand
|
|
4
|
+
* createVaporChamberApp, getVaporInteropPlugin, defineVaporCommand,
|
|
5
|
+
* useVaporCommand
|
|
5
6
|
*
|
|
6
7
|
* Separated from chamber.ts to keep the core composable module CDCC-compliant.
|
|
7
8
|
*/
|
|
8
|
-
import type { Handler, RegisterOptions, CommandResult } from './command-bus';
|
|
9
|
+
import type { Handler, RegisterOptions, CommandResult, Command } from './command-bus';
|
|
9
10
|
/**
|
|
10
11
|
* Create a Vapor app instance with vapor-chamber ready.
|
|
11
12
|
* Requires Vue 3.6+. Throws if Vapor is not available.
|
|
@@ -45,4 +46,27 @@ export declare function defineVaporCommand(action: string, handler: Handler, opt
|
|
|
45
46
|
dispatch: (target: any, payload?: any) => CommandResult;
|
|
46
47
|
dispose: () => void;
|
|
47
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* useVaporCommand — reactive command dispatch designed for Vapor components.
|
|
51
|
+
*
|
|
52
|
+
* Like useCommand() but safe for `<script setup vapor>` where
|
|
53
|
+
* getCurrentInstance() returns null. Provides reactive loading/error signals
|
|
54
|
+
* and relies exclusively on onScopeDispose for cleanup (no onUnmounted path).
|
|
55
|
+
*
|
|
56
|
+
* For fire-and-forget (no loading/error state), prefer defineVaporCommand().
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // In a <script setup vapor> component:
|
|
60
|
+
* import { useVaporCommand } from 'vapor-chamber';
|
|
61
|
+
* const { dispatch, loading, lastError } = useVaporCommand();
|
|
62
|
+
* dispatch('cartAdd', { id: product.id });
|
|
63
|
+
*/
|
|
64
|
+
export declare function useVaporCommand(): {
|
|
65
|
+
dispatch: (action: string, target: any, payload?: any) => CommandResult;
|
|
66
|
+
register: (action: string, handler: Handler, opts?: RegisterOptions) => () => void;
|
|
67
|
+
on: (pattern: string, listener: (cmd: Command, result: CommandResult) => void) => () => void;
|
|
68
|
+
loading: import("./chamber").Signal<boolean>;
|
|
69
|
+
lastError: import("./chamber").Signal<Error | null>;
|
|
70
|
+
dispose: () => void;
|
|
71
|
+
};
|
|
48
72
|
//# sourceMappingURL=chamber-vapor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chamber-vapor.d.ts","sourceRoot":"","sources":["../src/chamber-vapor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"chamber-vapor.d.ts","sourceRoot":"","sources":["../src/chamber-vapor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEtF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,GAAG,OASxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,IAAI,GAAG,GAAG,IAAI,CAElD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,eAAe;uBAKC,GAAG,YAAY,GAAG,KAAG,aAAa;;EAS7D;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe;uBAMH,MAAM,UAAU,GAAG,YAAY,GAAG,KAAG,aAAa;uBASlD,MAAM,WAAW,OAAO,SAAS,eAAe,KAAG,MAAM,IAAI;kBAMlE,MAAM,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,KAAG,MAAM,IAAI;;;;EAclG"}
|
package/dist/chamber-vapor.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* vapor-chamber — Vue 3.6+ Vapor-specific API
|
|
3
3
|
*
|
|
4
|
-
* createVaporChamberApp, getVaporInteropPlugin, defineVaporCommand
|
|
4
|
+
* createVaporChamberApp, getVaporInteropPlugin, defineVaporCommand,
|
|
5
|
+
* useVaporCommand
|
|
5
6
|
*
|
|
6
7
|
* Separated from chamber.ts to keep the core composable module CDCC-compliant.
|
|
7
8
|
*/
|
|
8
|
-
import { getCommandBus, tryAutoCleanup, getVaporAppFn, getVaporInteropRef, } from './chamber';
|
|
9
|
+
import { getCommandBus, signal, tryAutoCleanup, getVaporAppFn, getVaporInteropRef, } from './chamber';
|
|
9
10
|
/**
|
|
10
11
|
* Create a Vapor app instance with vapor-chamber ready.
|
|
11
12
|
* Requires Vue 3.6+. Throws if Vapor is not available.
|
|
@@ -60,3 +61,52 @@ export function defineVaporCommand(action, handler, options) {
|
|
|
60
61
|
tryAutoCleanup(dispose);
|
|
61
62
|
return { dispatch, dispose };
|
|
62
63
|
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// useVaporCommand
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/**
|
|
68
|
+
* useVaporCommand — reactive command dispatch designed for Vapor components.
|
|
69
|
+
*
|
|
70
|
+
* Like useCommand() but safe for `<script setup vapor>` where
|
|
71
|
+
* getCurrentInstance() returns null. Provides reactive loading/error signals
|
|
72
|
+
* and relies exclusively on onScopeDispose for cleanup (no onUnmounted path).
|
|
73
|
+
*
|
|
74
|
+
* For fire-and-forget (no loading/error state), prefer defineVaporCommand().
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // In a <script setup vapor> component:
|
|
78
|
+
* import { useVaporCommand } from 'vapor-chamber';
|
|
79
|
+
* const { dispatch, loading, lastError } = useVaporCommand();
|
|
80
|
+
* dispatch('cartAdd', { id: product.id });
|
|
81
|
+
*/
|
|
82
|
+
export function useVaporCommand() {
|
|
83
|
+
const bus = getCommandBus();
|
|
84
|
+
const loading = signal(false);
|
|
85
|
+
const lastError = signal(null);
|
|
86
|
+
const listeners = [];
|
|
87
|
+
function dispatch(action, target, payload) {
|
|
88
|
+
loading.value = true;
|
|
89
|
+
lastError.value = null;
|
|
90
|
+
const result = bus.dispatch(action, target, payload);
|
|
91
|
+
loading.value = false;
|
|
92
|
+
if (!result.ok)
|
|
93
|
+
lastError.value = result.error ?? null;
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
function register(action, handler, opts) {
|
|
97
|
+
const unregister = bus.register(action, handler, opts);
|
|
98
|
+
listeners.push(unregister);
|
|
99
|
+
return unregister;
|
|
100
|
+
}
|
|
101
|
+
function on(pattern, listener) {
|
|
102
|
+
const unsub = bus.on(pattern, listener);
|
|
103
|
+
listeners.push(unsub);
|
|
104
|
+
return unsub;
|
|
105
|
+
}
|
|
106
|
+
function dispose() {
|
|
107
|
+
listeners.forEach(fn => fn());
|
|
108
|
+
listeners.length = 0;
|
|
109
|
+
}
|
|
110
|
+
tryAutoCleanup(dispose);
|
|
111
|
+
return { dispatch, register, on, loading, lastError, dispose };
|
|
112
|
+
}
|
package/dist/chamber.d.ts
CHANGED
|
@@ -11,6 +11,16 @@ export type Signal<T> = {
|
|
|
11
11
|
value: T;
|
|
12
12
|
};
|
|
13
13
|
export type CreateSignal = <T>(initial: T) => Signal<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Wait for Vue detection to complete. Call this in app setup if you need
|
|
16
|
+
* to guarantee Vue APIs are available before the first signal() call.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* import { waitForVueDetection, signal } from 'vapor-chamber';
|
|
20
|
+
* await waitForVueDetection();
|
|
21
|
+
* const count = signal(0); // guaranteed to use Vue ref() if available
|
|
22
|
+
*/
|
|
23
|
+
export declare function waitForVueDetection(): Promise<void>;
|
|
14
24
|
/**
|
|
15
25
|
* Configure the signal factory used by vapor-chamber composables.
|
|
16
26
|
* Call this once at app setup when Vue Vapor's signal API is available.
|
package/dist/chamber.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chamber.d.ts","sourceRoot":"","sources":["../src/chamber.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAoB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMpK,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AACrC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"chamber.d.ts","sourceRoot":"","sources":["../src/chamber.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAoB,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAMpK,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AACrC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC;AAwFxD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGzD;AAoBD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAEtD;AAED,eAAO,MAAM,MAAM,EAAE,YAAoD,CAAC;AAM1E;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED,gDAAgD;AAChD,wBAAgB,aAAa,IAAI,GAAG,CAA8B;AAClE,gDAAgD;AAChD,wBAAgB,kBAAkB,IAAI,GAAG,CAAmC;AAQ5E,wBAAgB,aAAa,IAAI,UAAU,CAK1C;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAEnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAMD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,IAAI,GAAG,IAAI,CAoC1D;AAMD;;;;GAIG;AACH,wBAAgB,UAAU;uBAKE,MAAM,UAAU,GAAG,YAAY,GAAG,KAAG,aAAa;;;EAU7E;AAMD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,CAAC,EACV,QAAQ,EAAE;IACR,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;CACjD;;;EAuBF;AAMD;;GAEG;AACH,wBAAgB,aAAa,mDAE5B;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;CAC/B;;;;;gBAoBa,OAAO,GAAG,SAAS;gBAsBnB,OAAO,GAAG,SAAS;;;EAmCrC;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM;uBAQrB,MAAM,UAAU,GAAG,YAAY,GAAG,KAAG,aAAa;uBAIlD,MAAM,WAAW,OAAO,SAAS,eAAe,KAAG,MAAM,IAAI;kBAMlE,MAAM,KAAG,MAAM,IAAI;kBAMnB,MAAM,YAAY,QAAQ,KAAG,MAAM,IAAI;;;EAgB7D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE;IACvC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC;CAC/B;;aAIqB,OAAO;eAAS,KAAK;mBAAa,MAAM;;;;;EAyBlE"}
|