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.
Files changed (47) hide show
  1. package/README.md +322 -14
  2. package/dist/chamber-vapor.d.ts +26 -2
  3. package/dist/chamber-vapor.d.ts.map +1 -1
  4. package/dist/chamber-vapor.js +52 -2
  5. package/dist/chamber.d.ts +10 -0
  6. package/dist/chamber.d.ts.map +1 -1
  7. package/dist/chamber.js +68 -26
  8. package/dist/command-bus.d.ts +283 -11
  9. package/dist/command-bus.d.ts.map +1 -1
  10. package/dist/command-bus.js +549 -61
  11. package/dist/directives.d.ts.map +1 -1
  12. package/dist/directives.js +45 -12
  13. package/dist/form.d.ts +11 -0
  14. package/dist/form.d.ts.map +1 -1
  15. package/dist/form.js +36 -11
  16. package/dist/http.d.ts.map +1 -1
  17. package/dist/http.js +18 -9
  18. package/dist/index.d.ts +20 -7
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +30 -7
  21. package/dist/plugins-core.d.ts +61 -3
  22. package/dist/plugins-core.d.ts.map +1 -1
  23. package/dist/plugins-core.js +112 -6
  24. package/dist/plugins-extra.d.ts +116 -0
  25. package/dist/plugins-extra.d.ts.map +1 -0
  26. package/dist/plugins-extra.js +275 -0
  27. package/dist/plugins.d.ts +2 -2
  28. package/dist/plugins.d.ts.map +1 -1
  29. package/dist/plugins.js +2 -2
  30. package/dist/schema.d.ts +91 -13
  31. package/dist/schema.d.ts.map +1 -1
  32. package/dist/schema.js +177 -44
  33. package/dist/testing.d.ts +10 -2
  34. package/dist/testing.d.ts.map +1 -1
  35. package/dist/testing.js +118 -18
  36. package/dist/transports.d.ts +16 -0
  37. package/dist/transports.d.ts.map +1 -1
  38. package/dist/transports.js +30 -6
  39. package/dist/utilities.d.ts +100 -0
  40. package/dist/utilities.d.ts.map +1 -0
  41. package/dist/utilities.js +119 -0
  42. package/dist/vapor-chamber.iife.js +510 -83
  43. package/dist/vapor-chamber.iife.js.map +4 -4
  44. package/dist/vapor-chamber.iife.min.js +2 -2
  45. package/dist/vite-hmr.d.ts.map +1 -1
  46. package/dist/vite-hmr.js +3 -1
  47. 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 v0.5.0
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` | — | ⚠️ Requires Vue 3.6 runtime to test |
137
- | Vue | `directives.ts` | — | ⚠️ Requires Vue DOM environment to test |
138
- | Build | `devtools.ts` | — | ⚠️ Requires browser DevTools API to test |
139
- | Build | `vite-hmr.ts` | — | ⚠️ Requires Vite runtime to test |
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 v0.4.0 is aligned with Vue 3.6 beta. It works in three contexts:
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(); // → boolean
598
- ws.disconnect(); // intentional close — suppresses reconnect
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 | ⚠️ requires Vue 3.6 runtime |
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
- | `setupDevtools` — Vue DevTools panel | `devtools` | ✅ v0.4.0 | ⚠️ requires browser DevTools API |
1091
- | `createDirectivePlugin` — `v-command` directive | `directives` | ✅ v0.5.0 | ⚠️ requires Vue DOM environment |
1092
- | Vite HMR plugin | `vite-hmr` | ✅ v0.5.0 | ⚠️ requires Vite runtime |
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 (318/318, 0 failures) | ✅ Done |
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 |
@@ -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;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE7E;;;;;;;;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"}
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"}
@@ -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.
@@ -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;AAsFxD;;;;;;;;;;;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,CAuB1D;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"}
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"}