@alwatr/flux 9.16.0 → 9.18.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 CHANGED
@@ -52,7 +52,7 @@ No magic. No hidden re-renders. No performance cliffs.
52
52
 
53
53
  ### 3. **Absolute Type Safety**
54
54
 
55
- Through TypeScript's **Declaration Merging**, the entire action bus is fully typed:
55
+ Through TypeScript's **Declaration Merging**, the entire action bus is fully typed. Every action is a single **`Action<K>`** object (Alwatr Flux Standard Action — AFSA) carrying `type`, `payload`, `context`, and `meta`:
56
56
 
57
57
  ```typescript
58
58
  // Define your actions once
@@ -64,14 +64,16 @@ declare module '@alwatr/flux' {
64
64
  }
65
65
  }
66
66
 
67
- // Get compile-time safety everywhere
68
- onAction('add_to_cart', (item) => {
69
- // item is typed as {productId: number; qty: number}
70
- cartService.add(item.productId, item.qty);
67
+ // Get compile-time safety everywhere — handler receives the full Action object
68
+ onAction('add_to_cart', (action) => {
69
+ // action.payload is typed as {productId: number; qty: number}
70
+ cartService.add(action.payload.productId, action.payload.qty);
71
+ // action.context is the nearest [action-context] ancestor value (or undefined)
72
+ console.log(action.context); // e.g. 'product-list'
71
73
  });
72
74
 
73
- dispatchAction('add_to_cart', {productId: 42, qty: 1}); // ✅
74
- dispatchAction('add_to_cart', 'wrong'); // ❌ Compile error
75
+ dispatchAction({type: 'add_to_cart', payload: {productId: 42, qty: 1}}); // ✅
76
+ dispatchAction({type: 'add_to_cart', payload: 'wrong'}); // ❌ Compile error
75
77
  ```
76
78
 
77
79
  ---
@@ -120,7 +122,7 @@ lastName.set('Smith'); // Only fullName and the effect re-run — nothing else
120
122
 
121
123
  ### 🧩 **Declarative HTML Syntax**
122
124
 
123
- Connect DOM events to typed actions without writing JavaScript:
125
+ Connect DOM events to typed actions without writing JavaScript. Wrap elements in `[action-context]` to scope the same action type to different UI regions:
124
126
 
125
127
  ```html
126
128
  <!-- Simple action -->
@@ -153,6 +155,28 @@ Connect DOM events to typed actions without writing JavaScript:
153
155
 
154
156
  <!-- Fire once and remove -->
155
157
  <button on-click="track_impression:hero_banner; once">Learn More</button>
158
+
159
+ <!-- Context scoping — same action type, different regions -->
160
+ <section action-context="volume">
161
+ <input
162
+ type="range"
163
+ on-input="slider:change:$value"
164
+ />
165
+ </section>
166
+ <section action-context="brightness">
167
+ <input
168
+ type="range"
169
+ on-input="slider:change:$value"
170
+ />
171
+ </section>
172
+ ```
173
+
174
+ ```typescript
175
+ // Handler receives the full Action object — payload, context, and meta together
176
+ onAction('slider:change', (action) => {
177
+ if (action.context === 'volume') audioService.setVolume(Number(action.payload));
178
+ if (action.context === 'brightness') displayService.setBrightness(Number(action.payload));
179
+ });
156
180
  ```
157
181
 
158
182
  **Built-in modifiers:**
@@ -308,55 +332,59 @@ createEffect({
308
332
  Flux implements a **strict layered architecture** where each layer has a single responsibility:
309
333
 
310
334
  ```
311
- ┌─────────────────────────────────────────────────────────────┐
312
- │ VIEW LAYER
313
- │ (HTML templates, Directives, lit-html rendering)
314
-
315
- │ • Reads state from Signals
316
- │ • Dispatches Actions via on-<event> attributes
317
- │ • Never manipulates state directly
318
- └──────────────────┬──────────────────────────────────────────┘
335
+ ┌───────────────────────────────────────────────────────────┐
336
+ │ VIEW LAYER
337
+ │ (HTML templates, Directives, lit-html rendering)
338
+
339
+ │ • Reads state from Signals
340
+ │ • Dispatches Actions via on-<event> attributes
341
+ │ • Never manipulates state directly
342
+ └──────────────────┬────────────────────────────────────────┘
319
343
  │ on-click="add_to_cart:42"
320
344
 
321
- ┌─────────────────────────────────────────────────────────────┐
322
- │ ACTION LAYER
323
- │ (@alwatr/action — Global Event Delegation)
324
-
325
- │ • Captures DOM events via document.body listener
326
- │ • Parses on-<event> attributes
327
- │ • Runs modifiers (prevent, validate, once)
328
- │ • Resolves payload ($value, $formdata)
329
- │ • Dispatches typed action to ChannelSignal
330
- └──────────────────┬──────────────────────────────────────────┘
331
- dispatchAction('add_to_cart', 42)
345
+ ┌───────────────────────────────────────────────────────────┐
346
+ │ ACTION LAYER
347
+ │ (@alwatr/action — Global Event Delegation + AFSA)
348
+
349
+ │ • Captures DOM events via document.body listener
350
+ │ • Resolves [action-context] ancestor → action.context
351
+ │ • Parses on-<event> attributes
352
+ │ • Runs modifiers (prevent, validate, once)
353
+ │ • Modifiers may enrich action.meta
354
+ │ • Resolves payload ($value, $formdata) │
355
+ Dispatches full Action {type, payload, context, meta} │
356
+ └──────────────────┬────────────────────────────────────────┘
357
+ │ dispatchAction({type: 'add_to_cart', payload: 42, context: 'cart'})
332
358
 
333
- ┌─────────────────────────────────────────────────────────────┐
334
- │ CONTROLLER LAYER
335
- │ (Business Logic, Services, Use Cases)
336
-
337
- │ • Subscribes to Actions via onAction()
338
- │ • Executes business logic
339
- Updates State via Signal.set()
340
- │ • Never touches DOM directly
341
- └──────────────────┬──────────────────────────────────────────┘
359
+ ┌───────────────────────────────────────────────────────────┐
360
+ │ CONTROLLER LAYER
361
+ │ (Business Logic, Services, Use Cases)
362
+
363
+ │ • Subscribes to Actions via onAction()
364
+ │ • Receives full Action object (type, payload, context,
365
+ meta) no need to pass context separately
366
+ │ • Executes business logic
367
+ │ • Updates State via Signal.set() │
368
+ │ • Never touches DOM directly │
369
+ └──────────────────┬────────────────────────────────────────┘
342
370
  │ cartSignal.set(newCart)
343
371
 
344
- ┌─────────────────────────────────────────────────────────────┐
345
- │ STATE LAYER
346
- │ (@alwatr/signal — Reactive State Management)
347
-
348
- │ • StateSignal — mutable state
349
- │ • ComputedSignal — derived state (memoized)
350
- │ • EffectSignal — side effects
351
- │ • PersistentStateSignal — localStorage sync
352
- │ • SessionStateSignal — sessionStorage sync
353
- └──────────────────┬──────────────────────────────────────────┘
372
+ ┌───────────────────────────────────────────────────────────┐
373
+ │ STATE LAYER
374
+ │ (@alwatr/signal — Reactive State Management)
375
+
376
+ │ • StateSignal — mutable state
377
+ │ • ComputedSignal — derived state (memoized)
378
+ │ • EffectSignal — side effects
379
+ │ • PersistentStateSignal — localStorage sync
380
+ │ • SessionStateSignal — sessionStorage sync
381
+ └──────────────────┬────────────────────────────────────────┘
354
382
  │ signal.subscribe(render)
355
383
 
356
- ┌─────────────────────────────────────────────────────────────┐
357
- │ VIEW LAYER
358
- │ (Re-render only affected DOM nodes)
359
- └─────────────────────────────────────────────────────────────┘
384
+ ┌───────────────────────────────────────────────────────────┐
385
+ │ VIEW LAYER
386
+ │ (Re-render only affected DOM nodes)
387
+ └───────────────────────────────────────────────────────────┘
360
388
  ```
361
389
 
362
390
  **Key architectural benefits:**
@@ -369,6 +397,63 @@ Flux implements a **strict layered architecture** where each layer has a single
369
397
 
370
398
  ---
371
399
 
400
+ ## 🎯 The Action Object (AFSA)
401
+
402
+ Every action flowing through the bus — whether triggered from HTML attributes or dispatched programmatically — is a single **`Action<K>`** object (Alwatr Flux Standard Action):
403
+
404
+ ```typescript
405
+ interface Action<K extends keyof ActionRecord> {
406
+ /** Action identifier — must be a key of ActionRecord. */
407
+ type: K;
408
+
409
+ /**
410
+ * DOM context from the nearest [action-context] ancestor.
411
+ * undefined for programmatic dispatches or when no ancestor exists.
412
+ * Example: 'product-list', 'checkout-form', 'volume-slider'
413
+ */
414
+ context?: string;
415
+
416
+ /** Business payload — type is inferred from ActionRecord[K]. */
417
+ payload: ActionRecord[K];
418
+
419
+ /**
420
+ * Open-ended metadata bag for cross-cutting concerns.
421
+ * Modifiers in the delegation pipeline may write to this before
422
+ * the action reaches subscribers.
423
+ */
424
+ meta?: Record<string, unknown>;
425
+ }
426
+ ```
427
+
428
+ This unified structure replaces the previous two-argument `(id, payload)` API. Every handler now receives the full picture:
429
+
430
+ ```typescript
431
+ onAction('add_to_cart', (action) => {
432
+ console.log(action.type); // 'add_to_cart'
433
+ console.log(action.payload); // {productId: 42, qty: 1} — fully typed
434
+ console.log(action.context); // 'product-list' — from [action-context] ancestor
435
+ console.log(action.meta); // {traceId: '…'} — set by modifiers, or undefined
436
+ });
437
+ ```
438
+
439
+ Modifiers can enrich `meta` before the action reaches subscribers:
440
+
441
+ ```typescript
442
+ import {registerModifier} from '@alwatr/flux';
443
+
444
+ registerModifier('trace', (_event, _element, action) => {
445
+ action.meta ??= {};
446
+ action.meta['traceId'] = crypto.randomUUID();
447
+ return true;
448
+ });
449
+ ```
450
+
451
+ ```html
452
+ <button on-click="submit_order:42; trace">Place Order</button>
453
+ ```
454
+
455
+ ---
456
+
372
457
  ## 📦 Installation
373
458
 
374
459
  ```bash
@@ -443,8 +528,9 @@ onAction('decrement', () => {
443
528
  counterSignal.update((count) => count - 1);
444
529
  });
445
530
 
446
- onAction('set_count', (value) => {
447
- counterSignal.set(value);
531
+ // Handler receives the full Action object — payload is typed from ActionRecord
532
+ onAction('set_count', (action) => {
533
+ counterSignal.set(action.payload); // action.payload: number
448
534
  });
449
535
  ```
450
536
 
@@ -612,39 +698,56 @@ setupActionDelegation();
612
698
  setupActionDelegation([...DEFAULT_DELEGATED_EVENTS, 'keydown', 'focus']);
613
699
  ```
614
700
 
615
- #### `onAction<K>(actionId, handler)`
701
+ #### `onAction<K>(type, handler)`
616
702
 
617
- Subscribes to a typed action.
703
+ Subscribes to a typed action. The handler receives the full `Action<K>` object.
618
704
 
619
705
  ```typescript
620
- const sub = onAction('add_to_cart', (item) => {
621
- cartService.add(item.productId, item.qty);
706
+ const sub = onAction('add_to_cart', (action) => {
707
+ cartService.add(action.payload.productId, action.payload.qty);
708
+ console.log(action.context); // e.g. 'product-list' or undefined
709
+ console.log(action.meta); // any metadata set by modifiers
622
710
  });
623
711
 
624
712
  sub.unsubscribe(); // Clean up when done
625
713
  ```
626
714
 
627
- #### `dispatchAction<K>(actionId, payload?)`
715
+ #### `dispatchAction<K>(action)`
628
716
 
629
- Dispatches a typed action programmatically.
717
+ Dispatches a typed action programmatically. Takes a full `Action<K>` object.
630
718
 
631
719
  ```typescript
632
- dispatchAction('navigate', '/home');
633
- dispatchAction('logout'); // void payload
720
+ dispatchAction({type: 'navigate', payload: '/home'});
721
+ dispatchAction({type: 'logout', payload: undefined}); // void payload
722
+
723
+ // With context and meta
724
+ dispatchAction({
725
+ type: 'add_to_cart',
726
+ payload: {productId: 42, qty: 1},
727
+ context: 'product-list',
728
+ meta: {source: 'recommendation'},
729
+ });
634
730
  ```
635
731
 
636
732
  #### `registerModifier(name, handler)`
637
733
 
638
- Adds a custom modifier for `on-<event>` attributes.
734
+ Adds a custom modifier for `on-<event>` attributes. The handler receives the mutable `action` object and may write to `action.meta`.
639
735
 
640
736
  ```typescript
641
737
  registerModifier('confirm', () => {
642
738
  return window.confirm('Are you sure?');
643
739
  });
740
+
741
+ // A modifier that stamps a trace ID into meta
742
+ registerModifier('trace', (_event, _element, action) => {
743
+ action.meta ??= {};
744
+ action.meta['traceId'] = crypto.randomUUID();
745
+ return true;
746
+ });
644
747
  ```
645
748
 
646
749
  ```html
647
- <button on-click="delete_item:42; confirm">Delete</button>
750
+ <button on-click="delete_item:42; confirm,trace">Delete</button>
648
751
  ```
649
752
 
650
753
  #### `registerPayloadResolver(name, resolver)`
@@ -842,6 +945,123 @@ renderState(currentState, {
842
945
 
843
946
  ---
844
947
 
948
+ ### Template (lit-html)
949
+
950
+ `@alwatr/flux` re-exports a curated subset of [`lit-html`](https://lit.dev/docs/libraries/standalone-templates/) so you can render efficient DOM templates without adding a separate dependency.
951
+
952
+ #### `html`
953
+
954
+ Tagged template literal that produces a `TemplateResult`. lit-html parses the template once and only updates the dynamic parts on subsequent renders.
955
+
956
+ ```typescript
957
+ import {html} from '@alwatr/flux';
958
+
959
+ const greeting = (name: string) => html`
960
+ <p>Hello, ${name}!</p>
961
+ `;
962
+ ```
963
+
964
+ #### `render(value, container)`
965
+
966
+ Renders a `TemplateResult` (or any renderable value) into a DOM container. Subsequent calls efficiently patch only the changed parts.
967
+
968
+ ```typescript
969
+ import {html, render} from '@alwatr/flux';
970
+
971
+ render(
972
+ html`
973
+ <h1>Hello World</h1>
974
+ `,
975
+ document.getElementById('app')!,
976
+ );
977
+ ```
978
+
979
+ #### `noChange` / `nothing`
980
+
981
+ Sentinels for fine-grained control over part updates:
982
+
983
+ - **`noChange`** — leaves the current DOM value untouched (skips the update entirely)
984
+ - **`nothing`** — removes the node or attribute from the DOM
985
+
986
+ ```typescript
987
+ import {html, noChange, nothing} from '@alwatr/flux';
988
+
989
+ const badge = (count: number | undefined) => html`
990
+ <span class="badge">
991
+ ${count === undefined ? nothing
992
+ : count === 0 ? noChange
993
+ : count}
994
+ </span>
995
+ `;
996
+ ```
997
+
998
+ #### `ifDefined(value)`
999
+
1000
+ Renders the attribute only when `value` is not `undefined`; removes the attribute otherwise.
1001
+
1002
+ ```typescript
1003
+ import {html, ifDefined} from '@alwatr/flux';
1004
+
1005
+ const link = (href?: string) => html`
1006
+ <a href=${ifDefined(href)}>Click</a>
1007
+ `;
1008
+ ```
1009
+
1010
+ #### `cache(value)`
1011
+
1012
+ Caches rendered templates keyed by their `TemplateResult` identity. Avoids re-parsing the template string when switching between a fixed set of templates (e.g. tab panels).
1013
+
1014
+ ```typescript
1015
+ import {html, cache} from '@alwatr/flux';
1016
+
1017
+ const panel = (tab: 'home' | 'settings') =>
1018
+ cache(
1019
+ tab === 'home' ?
1020
+ html`
1021
+ <home-panel></home-panel>
1022
+ `
1023
+ : html`
1024
+ <settings-panel></settings-panel>
1025
+ `,
1026
+ );
1027
+ ```
1028
+
1029
+ #### `classMap(classInfo)`
1030
+
1031
+ Efficiently toggles CSS classes from a `{[className]: boolean}` object. Only the classes present in the map are touched; others are left unchanged.
1032
+
1033
+ ```typescript
1034
+ import {html, classMap} from '@alwatr/flux';
1035
+
1036
+ const button = (isActive: boolean, isDisabled: boolean) => html`
1037
+ <button class=${classMap({active: isActive, disabled: isDisabled})}>Click</button>
1038
+ `;
1039
+ ```
1040
+
1041
+ #### `when(condition, trueCase, falseCase?)`
1042
+
1043
+ Conditional rendering helper. Cleaner than ternary expressions for template branches.
1044
+
1045
+ ```typescript
1046
+ import {html, when} from '@alwatr/flux';
1047
+
1048
+ const status = (isLoading: boolean) => html`
1049
+ <div>
1050
+ ${when(
1051
+ isLoading,
1052
+ () => html`
1053
+ <spinner-element></spinner-element>
1054
+ `,
1055
+ () => html`
1056
+ <content-element></content-element>
1057
+ `,
1058
+ )}
1059
+ </div>
1060
+ `;
1061
+ ```
1062
+
1063
+ ---
1064
+
845
1065
  ## 🆚 Why Choose Alwatr Flux?
846
1066
 
847
1067
  | Feature | React + Redux | Solid.js | Svelte | **Alwatr Flux** 🌊 |
@@ -889,23 +1109,23 @@ import {todosSignal} from './state.js';
889
1109
 
890
1110
  let nextId = 1;
891
1111
 
892
- onAction('add_todo', (text) => {
1112
+ onAction('add_todo', (action) => {
893
1113
  todosSignal.update((todos) => [
894
1114
  ...todos,
895
- {id: nextId++, text, done: false},
1115
+ {id: nextId++, text: action.payload, done: false},
896
1116
  ]);
897
1117
  });
898
1118
 
899
- onAction('toggle_todo', (id) => {
1119
+ onAction('toggle_todo', (action) => {
900
1120
  todosSignal.update((todos) =>
901
1121
  todos.map((todo) =>
902
- todo.id === id ? {...todo, done: !todo.done} : todo
1122
+ todo.id === action.payload ? {...todo, done: !todo.done} : todo
903
1123
  )
904
1124
  );
905
1125
  });
906
1126
 
907
- onAction('remove_todo', (id) => {
908
- todosSignal.update((todos) => todos.filter((t) => t.id !== id));
1127
+ onAction('remove_todo', (action) => {
1128
+ todosSignal.update((todos) => todos.filter((t) => t.id !== action.payload));
909
1129
  });
910
1130
 
911
1131
  // view.html
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Curated re-exports from `lit-html` for use within `@alwatr/flux`.
3
+ *
4
+ * Only the subset of `lit-html` APIs that are commonly needed in a Flux-based
5
+ * application is exported here. This keeps the public surface minimal and
6
+ * avoids pulling in advanced directive utilities that most consumers never use.
7
+ *
8
+ * **Exported APIs:**
9
+ * - `html` — tagged template literal that produces a `TemplateResult`
10
+ * - `render` — renders a `TemplateResult` into a DOM container
11
+ * - `noChange` — sentinel that tells lit-html to leave the current part value unchanged
12
+ * - `nothing` — sentinel that renders nothing (removes the node/attribute)
13
+ * - `ifDefined` — renders a value only when it is not `undefined`
14
+ * - `cache` — caches rendered templates to avoid re-parsing on state changes
15
+ * - `classMap` — efficiently sets/removes CSS classes from an object map
16
+ * - `when` — conditional rendering helper (`when(condition, trueCase, falseCase)`)
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import {html, render, classMap, when} from '@alwatr/flux';
21
+ *
22
+ * const template = (isActive: boolean) => html`
23
+ * <div class=${classMap({active: isActive, hidden: !isActive})}>
24
+ * ${when(isActive, () => html`<span>Active</span>`, () => html`<span>Inactive</span>`)}
25
+ * </div>
26
+ * `;
27
+ *
28
+ * render(template(true), document.getElementById('app')!);
29
+ * ```
30
+ */
31
+ export { html, render, noChange, nothing } from 'lit-html';
32
+ export { ifDefined } from 'lit-html/directives/if-defined.js';
33
+ export { cache } from 'lit-html/directives/cache.js';
34
+ export { classMap } from 'lit-html/directives/class-map.js';
35
+ export { when } from 'lit-html/directives/when.js';
36
+ //# sourceMappingURL=lit-html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lit-html.d.ts","sourceRoot":"","sources":["../src/lit-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,EAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAC,MAAM,UAAU,CAAC;AAIzD,OAAO,EAAC,SAAS,EAAC,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAC,KAAK,EAAC,MAAM,8BAA8B,CAAC;AACnD,OAAO,EAAC,QAAQ,EAAC,MAAM,kCAAkC,CAAC;AAC1D,OAAO,EAAC,IAAI,EAAC,MAAM,6BAA6B,CAAC"}
package/dist/main.d.ts CHANGED
@@ -5,5 +5,6 @@ export * from '@alwatr/render-state';
5
5
  export * from '@alwatr/local-storage';
6
6
  export * from '@alwatr/session-storage';
7
7
  export * from '@alwatr/page-ready';
8
+ export * from './lit-html.js';
8
9
  export type * from '@alwatr/type-helper';
9
10
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,mBAAmB,qBAAqB,CAAC"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAGA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,mBAAmB,qBAAqB,CAAC"}
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
- /* 📦 @alwatr/flux v9.16.0 */
2
- export*from"@alwatr/signal";export*from"@alwatr/action";export*from"@alwatr/directive";export*from"@alwatr/render-state";export*from"@alwatr/local-storage";export*from"@alwatr/session-storage";export*from"@alwatr/page-ready";
1
+ /* 📦 @alwatr/flux v9.18.0 */
2
+ export*from"@alwatr/signal";export*from"@alwatr/action";export*from"@alwatr/directive";export*from"@alwatr/render-state";export*from"@alwatr/local-storage";export*from"@alwatr/session-storage";export*from"@alwatr/page-ready";import{html as o,render as a,noChange as t,nothing as p}from"lit-html";import{ifDefined as f}from"lit-html/directives/if-defined.js";import{cache as g}from"lit-html/directives/cache.js";import{classMap as i}from"lit-html/directives/class-map.js";import{when as s}from"lit-html/directives/when.js";export{s as when,a as render,p as nothing,t as noChange,f as ifDefined,o as html,i as classMap,g as cache};
3
3
 
4
- //# debugId=C06C2CEF2EC7ADAE64756E2164756E21
4
+ //# debugId=432FAE968752561764756E2164756E21
5
5
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/main.ts"],
3
+ "sources": ["../src/main.ts", "../src/lit-html.ts"],
4
4
  "sourcesContent": [
5
- "// UI and reactive bundle — signals, actions, directives, and client-side storage.\n// This package aggregates all UI-layer nanolibs for convenient single-import usage.\n\nexport * from '@alwatr/signal';\nexport * from '@alwatr/action';\nexport * from '@alwatr/directive';\nexport * from '@alwatr/render-state';\nexport * from '@alwatr/local-storage';\nexport * from '@alwatr/session-storage';\nexport * from '@alwatr/page-ready';\nexport type * from '@alwatr/type-helper';\n"
5
+ "// UI and reactive bundle — signals, actions, directives, and client-side storage.\n// This package aggregates all UI-layer nanolibs for convenient single-import usage.\n\nexport * from '@alwatr/signal';\nexport * from '@alwatr/action';\nexport * from '@alwatr/directive';\nexport * from '@alwatr/render-state';\nexport * from '@alwatr/local-storage';\nexport * from '@alwatr/session-storage';\nexport * from '@alwatr/page-ready';\nexport * from './lit-html.js';\nexport type * from '@alwatr/type-helper';\n",
6
+ "/**\n * Curated re-exports from `lit-html` for use within `@alwatr/flux`.\n *\n * Only the subset of `lit-html` APIs that are commonly needed in a Flux-based\n * application is exported here. This keeps the public surface minimal and\n * avoids pulling in advanced directive utilities that most consumers never use.\n *\n * **Exported APIs:**\n * - `html` — tagged template literal that produces a `TemplateResult`\n * - `render` — renders a `TemplateResult` into a DOM container\n * - `noChange` — sentinel that tells lit-html to leave the current part value unchanged\n * - `nothing` — sentinel that renders nothing (removes the node/attribute)\n * - `ifDefined` — renders a value only when it is not `undefined`\n * - `cache` — caches rendered templates to avoid re-parsing on state changes\n * - `classMap` — efficiently sets/removes CSS classes from an object map\n * - `when` — conditional rendering helper (`when(condition, trueCase, falseCase)`)\n *\n * @example\n * ```typescript\n * import {html, render, classMap, when} from '@alwatr/flux';\n *\n * const template = (isActive: boolean) => html`\n * <div class=${classMap({active: isActive, hidden: !isActive})}>\n * ${when(isActive, () => html`<span>Active</span>`, () => html`<span>Inactive</span>`)}\n * </div>\n * `;\n *\n * render(template(true), document.getElementById('app')!);\n * ```\n */\nexport {html, render, noChange, nothing} from 'lit-html';\n// export {Directive, PartType, directive} from 'lit-html/directive.js';\n// export {AsyncDirective} from 'lit-html/async-directive.js';\n// export {unsafeSVG} from 'lit-html/directives/unsafe-svg.js';\nexport {ifDefined} from 'lit-html/directives/if-defined.js';\nexport {cache} from 'lit-html/directives/cache.js';\nexport {classMap} from 'lit-html/directives/class-map.js';\nexport {when} from 'lit-html/directives/when.js';\n\n// export type {Part, PartInfo} from 'lit-html/directive.js';\n// export type {LitUnstable} from 'lit-html';\n"
6
7
  ],
7
- "mappings": ";AAGA,4BACA,4BACA,+BACA,kCACA,mCACA,qCACA",
8
- "debugId": "C06C2CEF2EC7ADAE64756E2164756E21",
8
+ "mappings": ";AAGA,4BACA,4BACA,+BACA,kCACA,mCACA,qCACA,gCCqBA,eAAQ,YAAM,cAAQ,aAAU,iBAIhC,oBAAQ,0CACR,gBAAQ,qCACR,mBAAQ,yCACR,eAAQ",
9
+ "debugId": "432FAE968752561764756E2164756E21",
9
10
  "names": []
10
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/flux",
3
- "version": "9.16.0",
3
+ "version": "9.18.0",
4
4
  "description": "UI and reactive library bundle for ECMAScript (JavaScript/TypeScript) projects — signals, actions, directives, and storage.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com> (https://ali.mihandoost.com)",
@@ -21,14 +21,15 @@
21
21
  },
22
22
  "sideEffects": false,
23
23
  "dependencies": {
24
- "@alwatr/action": "9.16.0",
25
- "@alwatr/directive": "9.16.0",
24
+ "@alwatr/action": "9.17.0",
25
+ "@alwatr/directive": "9.18.0",
26
26
  "@alwatr/local-storage": "9.16.0",
27
27
  "@alwatr/page-ready": "9.16.0",
28
28
  "@alwatr/render-state": "9.16.0",
29
29
  "@alwatr/session-storage": "9.16.0",
30
30
  "@alwatr/signal": "9.16.0",
31
- "@alwatr/type-helper": "9.14.0"
31
+ "@alwatr/type-helper": "9.14.0",
32
+ "lit-html": "^3.3.2"
32
33
  },
33
34
  "devDependencies": {
34
35
  "@alwatr/nano-build": "9.14.0",
@@ -38,7 +39,7 @@
38
39
  "scripts": {
39
40
  "b": "bun run build",
40
41
  "build": "bun run build:ts && bun run build:es",
41
- "build:es": "nano-build --preset=module src/*.ts",
42
+ "build:es": "nano-build --preset=module src/main.ts",
42
43
  "build:ts": "tsc --build",
43
44
  "cl": "bun run clean",
44
45
  "clean": "rm -rfv dist *.tsbuildinfo",
@@ -81,5 +82,5 @@
81
82
  "ui",
82
83
  "unidirectional-data-flow"
83
84
  ],
84
- "gitHead": "c210044f6e8ab444ec2f9e600f095761cbd279bd"
85
+ "gitHead": "ae7aed95106fd2e6d3c14f0628fc12ae8a29ea15"
85
86
  }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Curated re-exports from `lit-html` for use within `@alwatr/flux`.
3
+ *
4
+ * Only the subset of `lit-html` APIs that are commonly needed in a Flux-based
5
+ * application is exported here. This keeps the public surface minimal and
6
+ * avoids pulling in advanced directive utilities that most consumers never use.
7
+ *
8
+ * **Exported APIs:**
9
+ * - `html` — tagged template literal that produces a `TemplateResult`
10
+ * - `render` — renders a `TemplateResult` into a DOM container
11
+ * - `noChange` — sentinel that tells lit-html to leave the current part value unchanged
12
+ * - `nothing` — sentinel that renders nothing (removes the node/attribute)
13
+ * - `ifDefined` — renders a value only when it is not `undefined`
14
+ * - `cache` — caches rendered templates to avoid re-parsing on state changes
15
+ * - `classMap` — efficiently sets/removes CSS classes from an object map
16
+ * - `when` — conditional rendering helper (`when(condition, trueCase, falseCase)`)
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import {html, render, classMap, when} from '@alwatr/flux';
21
+ *
22
+ * const template = (isActive: boolean) => html`
23
+ * <div class=${classMap({active: isActive, hidden: !isActive})}>
24
+ * ${when(isActive, () => html`<span>Active</span>`, () => html`<span>Inactive</span>`)}
25
+ * </div>
26
+ * `;
27
+ *
28
+ * render(template(true), document.getElementById('app')!);
29
+ * ```
30
+ */
31
+ export {html, render, noChange, nothing} from 'lit-html';
32
+ // export {Directive, PartType, directive} from 'lit-html/directive.js';
33
+ // export {AsyncDirective} from 'lit-html/async-directive.js';
34
+ // export {unsafeSVG} from 'lit-html/directives/unsafe-svg.js';
35
+ export {ifDefined} from 'lit-html/directives/if-defined.js';
36
+ export {cache} from 'lit-html/directives/cache.js';
37
+ export {classMap} from 'lit-html/directives/class-map.js';
38
+ export {when} from 'lit-html/directives/when.js';
39
+
40
+ // export type {Part, PartInfo} from 'lit-html/directive.js';
41
+ // export type {LitUnstable} from 'lit-html';
package/src/main.ts CHANGED
@@ -8,4 +8,5 @@ export * from '@alwatr/render-state';
8
8
  export * from '@alwatr/local-storage';
9
9
  export * from '@alwatr/session-storage';
10
10
  export * from '@alwatr/page-ready';
11
+ export * from './lit-html.js';
11
12
  export type * from '@alwatr/type-helper';