@alwatr/flux 9.20.0 → 9.21.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
@@ -58,22 +58,22 @@ Through TypeScript's **Declaration Merging**, the entire action bus is fully typ
58
58
  // Define your actions once
59
59
  declare module '@alwatr/flux' {
60
60
  interface ActionRecord {
61
- 'ui:add_to_cart': {productId: number; qty: number};
62
- 'ui:open_drawer': 'menu' | 'settings';
63
- 'ui:logout': void;
61
+ ui_add_to_cart: {productId: number; qty: number};
62
+ ui_open_drawer: 'menu' | 'settings';
63
+ ui_logout: void;
64
64
  }
65
65
  }
66
66
 
67
67
  // Get compile-time safety everywhere — handler receives the full Action object
68
- onAction('ui:add_to_cart', (action) => {
68
+ onAction('ui_add_to_cart', (action) => {
69
69
  // action.payload is typed as {productId: number; qty: number}
70
70
  cartService.add(action.payload.productId, action.payload.qty);
71
71
  // action.context is the nearest [action-context] ancestor value (or undefined)
72
72
  console.log(action.context); // e.g. 'product-list'
73
73
  });
74
74
 
75
- dispatchAction({type: 'ui:add_to_cart', payload: {productId: 42, qty: 1}}); // ✅
76
- dispatchAction({type: 'ui:add_to_cart', payload: 'wrong'}); // ❌ Compile error
75
+ dispatchAction({type: 'ui_add_to_cart', payload: {productId: 42, qty: 1}}); // ✅
76
+ dispatchAction({type: 'ui_add_to_cart', payload: 'wrong'}); // ❌ Compile error
77
77
  ```
78
78
 
79
79
  ---
@@ -126,17 +126,17 @@ Connect DOM events to typed actions without writing JavaScript. Wrap elements in
126
126
 
127
127
  ```html
128
128
  <!-- Simple action -->
129
- <button on-click="ui:open_drawer:menu">Menu</button>
129
+ <button on-click="ui_open_drawer:menu">Menu</button>
130
130
 
131
131
  <!-- Dynamic payload from input value -->
132
132
  <input
133
- on-input="ui:search_query:$value"
133
+ on-input="ui_search_query:$value"
134
134
  placeholder="Search..."
135
135
  />
136
136
 
137
137
  <!-- Form submission with validation -->
138
138
  <form
139
- on-submit="ui:submit_form:$formdata; prevent,validate"
139
+ on-submit="ui_submit_form:$formdata; prevent,validate"
140
140
  novalidate
141
141
  >
142
142
  <input
@@ -150,30 +150,30 @@ Connect DOM events to typed actions without writing JavaScript. Wrap elements in
150
150
  <!-- Checkbox state -->
151
151
  <input
152
152
  type="checkbox"
153
- on-change="ui:toggle_feature:$checked"
153
+ on-change="ui_toggle_feature:$checked"
154
154
  />
155
155
 
156
156
  <!-- Fire once and remove -->
157
- <button on-click="ui:track_impression:hero_banner; once">Learn More</button>
157
+ <button on-click="ui_track_impression:hero_banner; once">Learn More</button>
158
158
 
159
159
  <!-- Context scoping — same action type, different regions -->
160
160
  <section action-context="volume">
161
161
  <input
162
162
  type="range"
163
- on-input="ui:slider_change:$value"
163
+ on-input="ui_slider_change:$value"
164
164
  />
165
165
  </section>
166
166
  <section action-context="brightness">
167
167
  <input
168
168
  type="range"
169
- on-input="ui:slider_change:$value"
169
+ on-input="ui_slider_change:$value"
170
170
  />
171
171
  </section>
172
172
  ```
173
173
 
174
174
  ```typescript
175
175
  // Handler receives the full Action object — payload, context, and meta together
176
- onAction('ui:slider_change', (action) => {
176
+ onAction('ui_slider_change', (action) => {
177
177
  if (action.context === 'volume') audioService.setVolume(Number(action.payload));
178
178
  if (action.context === 'brightness') displayService.setBrightness(Number(action.payload));
179
179
  });
@@ -392,7 +392,7 @@ Flux implements a **strict layered architecture** where each layer has a single
392
392
  │ • Dispatches Actions via on-<event> attributes │
393
393
  │ • Never manipulates state directly │
394
394
  └──────────────────┬────────────────────────────────────────┘
395
- │ on-click="ui:add_to_cart:42"
395
+ │ on-click="ui_add_to_cart:42"
396
396
 
397
397
  ┌───────────────────────────────────────────────────────────┐
398
398
  │ ACTION LAYER │
@@ -406,7 +406,7 @@ Flux implements a **strict layered architecture** where each layer has a single
406
406
  │ • Resolves payload ($value, $formdata) │
407
407
  │ • Dispatches full Action {type, payload, context, meta} │
408
408
  └──────────────────┬────────────────────────────────────────┘
409
- │ dispatchAction({type: 'ui:add_to_cart', payload: 42, context: 'cart'})
409
+ │ dispatchAction({type: 'ui_add_to_cart', payload: 42, context: 'cart'})
410
410
 
411
411
  ┌───────────────────────────────────────────────────────────┐
412
412
  │ CONTROLLER LAYER │
@@ -480,8 +480,8 @@ interface Action<K extends keyof ActionRecord> {
480
480
  This unified structure replaces the previous two-argument `(id, payload)` API. Every handler now receives the full picture:
481
481
 
482
482
  ```typescript
483
- onAction('ui:add_to_cart', (action) => {
484
- console.log(action.type); // 'ui:add_to_cart'
483
+ onAction('ui_add_to_cart', (action) => {
484
+ console.log(action.type); // 'ui_add_to_cart'
485
485
  console.log(action.payload); // {productId: 42, qty: 1} — fully typed
486
486
  console.log(action.context); // 'product-list' — from [action-context] ancestor
487
487
  console.log(action.meta); // {traceId: '…'} — set by modifiers, or undefined
@@ -501,7 +501,7 @@ registerModifier('trace', (_event, _element, action) => {
501
501
  ```
502
502
 
503
503
  ```html
504
- <button on-click="ui:submit_order:42; trace">Place Order</button>
504
+ <button on-click="ui_submit_order:42; trace">Place Order</button>
505
505
  ```
506
506
 
507
507
  ---
@@ -546,9 +546,9 @@ dispatchPageReady();
546
546
  // src/actions.ts
547
547
  declare module '@alwatr/flux' {
548
548
  interface ActionRecord {
549
- 'ui:increment': void;
550
- 'ui:decrement': void;
551
- 'ui:set_count': number;
549
+ ui_increment: void;
550
+ ui_decrement: void;
551
+ ui_set_count: number;
552
552
  }
553
553
  }
554
554
  ```
@@ -572,16 +572,16 @@ export const counterSignal = createStateSignal({
572
572
  import {onAction} from '@alwatr/flux';
573
573
  import {counterSignal} from './state.js';
574
574
 
575
- onAction('ui:increment', () => {
575
+ onAction('ui_increment', () => {
576
576
  counterSignal.update((count) => count + 1);
577
577
  });
578
578
 
579
- onAction('ui:decrement', () => {
579
+ onAction('ui_decrement', () => {
580
580
  counterSignal.update((count) => count - 1);
581
581
  });
582
582
 
583
583
  // Handler receives the full Action object — payload is typed from ActionRecord
584
- onAction('ui:set_count', (action) => {
584
+ onAction('ui_set_count', (action) => {
585
585
  counterSignal.set(action.payload); // action.payload: number
586
586
  });
587
587
  ```
@@ -597,11 +597,11 @@ onAction('ui:set_count', (action) => {
597
597
  Counter:
598
598
  <span id="count">0</span>
599
599
  </h1>
600
- <button on-click="ui:decrement">-</button>
601
- <button on-click="ui:increment">+</button>
600
+ <button on-click="ui_decrement">-</button>
601
+ <button on-click="ui_increment">+</button>
602
602
  <input
603
603
  type="number"
604
- on-input="ui:set_count:$value"
604
+ on-input="ui_set_count:$value"
605
605
  value="0"
606
606
  />
607
607
  </div>
@@ -755,7 +755,7 @@ setupActionDelegation([...DEFAULT_DELEGATED_EVENTS, 'keydown', 'focus']);
755
755
  Subscribes to a typed action. The handler receives the full `Action<K>` object.
756
756
 
757
757
  ```typescript
758
- const sub = onAction('ui:add_to_cart', (action) => {
758
+ const sub = onAction('ui_add_to_cart', (action) => {
759
759
  cartService.add(action.payload.productId, action.payload.qty);
760
760
  console.log(action.context); // e.g. 'product-list' or undefined
761
761
  console.log(action.meta); // any metadata set by modifiers
@@ -799,7 +799,7 @@ registerModifier('trace', (_event, _element, action) => {
799
799
  ```
800
800
 
801
801
  ```html
802
- <button on-click="ui:delete_item:42; confirm,trace">Delete</button>
802
+ <button on-click="ui_delete_item:42; confirm,trace">Delete</button>
803
803
  ```
804
804
 
805
805
  #### `registerPayloadResolver(name, resolver)`
@@ -814,7 +814,7 @@ registerPayloadResolver('$data-id', (_event, element) => {
814
814
 
815
815
  ```html
816
816
  <button
817
- on-click="ui:select:$data-id"
817
+ on-click="ui_select:$data-id"
818
818
  data-id="42"
819
819
  >
820
820
  Select
@@ -1210,9 +1210,9 @@ const status = (isLoading: boolean) => html`
1210
1210
  // actions.ts
1211
1211
  declare module '@alwatr/flux' {
1212
1212
  interface ActionRecord {
1213
- 'ui:add_todo': string;
1214
- 'ui:toggle_todo': number;
1215
- 'ui:remove_todo': number;
1213
+ 'ui_add_todo': string;
1214
+ 'ui_toggle_todo': number;
1215
+ 'ui_remove_todo': number;
1216
1216
  }
1217
1217
  }
1218
1218
 
@@ -1236,14 +1236,14 @@ import {todosSignal} from './state.js';
1236
1236
 
1237
1237
  let nextId = 1;
1238
1238
 
1239
- onAction('ui:add_todo', (action) => {
1239
+ onAction('ui_add_todo', (action) => {
1240
1240
  todosSignal.update((todos) => [
1241
1241
  ...todos,
1242
1242
  {id: nextId++, text: action.payload, done: false},
1243
1243
  ]);
1244
1244
  });
1245
1245
 
1246
- onAction('ui:toggle_todo', (action) => {
1246
+ onAction('ui_toggle_todo', (action) => {
1247
1247
  todosSignal.update((todos) =>
1248
1248
  todos.map((todo) =>
1249
1249
  todo.id === action.payload ? {...todo, done: !todo.done} : todo
@@ -1251,13 +1251,13 @@ onAction('ui:toggle_todo', (action) => {
1251
1251
  );
1252
1252
  });
1253
1253
 
1254
- onAction('ui:remove_todo', (action) => {
1254
+ onAction('ui_remove_todo', (action) => {
1255
1255
  todosSignal.update((todos) => todos.filter((t) => t.id !== action.payload));
1256
1256
  });
1257
1257
 
1258
1258
  // view.html
1259
1259
  <div id="app">
1260
- <input id="new-todo" on-change="ui:add_todo:$value" placeholder="What needs to be done?" />
1260
+ <input id="new-todo" on-change="ui_add_todo:$value" placeholder="What needs to be done?" />
1261
1261
  <ul id="todo-list"></ul>
1262
1262
  </div>
1263
1263
 
@@ -1276,10 +1276,10 @@ todosSignal.subscribe((todos) => {
1276
1276
  <input
1277
1277
  type="checkbox"
1278
1278
  .checked=${todo.done}
1279
- on-change="ui:toggle_todo:${todo.id}"
1279
+ on-change="ui_toggle_todo:${todo.id}"
1280
1280
  />
1281
1281
  <span style="${todo.done ? 'text-decoration: line-through' : ''}">${todo.text}</span>
1282
- <button on-click="ui:remove_todo:${todo.id}">×</button>
1282
+ <button on-click="ui_remove_todo:${todo.id}">×</button>
1283
1283
  </li>
1284
1284
  `)}
1285
1285
  `,
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
- /* 📦 @alwatr/flux v9.20.0 */
1
+ /* 📦 @alwatr/flux v9.21.0 */
2
2
  export*from"@alwatr/signal";export*from"@alwatr/action";export*from"@alwatr/directive";export*from"@alwatr/embedded-data";export*from"@alwatr/render-state";export*from"@alwatr/local-storage";export*from"@alwatr/session-storage";export*from"@alwatr/page-ready";import{html as e,render as t,noChange as a,nothing as p}from"lit-html";import{ifDefined as n}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,t as render,p as nothing,a as noChange,n as ifDefined,e as html,i as classMap,g as cache};
3
3
 
4
- //# debugId=FFDF9C9E1A81FDA864756E2164756E21
4
+ //# debugId=8181BA1BE55A167464756E2164756E21
5
5
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -6,6 +6,6 @@
6
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"
7
7
  ],
8
8
  "mappings": ";AAGA,4BACA,4BACA,+BACA,mCACA,kCACA,mCACA,qCACA,gCCoBA,eAAQ,YAAM,cAAQ,aAAU,iBAIhC,oBAAQ,0CACR,gBAAQ,qCACR,mBAAQ,yCACR,eAAQ",
9
- "debugId": "FFDF9C9E1A81FDA864756E2164756E21",
9
+ "debugId": "8181BA1BE55A167464756E2164756E21",
10
10
  "names": []
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/flux",
3
- "version": "9.20.0",
3
+ "version": "9.21.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,14 @@
21
21
  },
22
22
  "sideEffects": false,
23
23
  "dependencies": {
24
- "@alwatr/action": "9.20.0",
25
- "@alwatr/directive": "9.20.0",
26
- "@alwatr/embedded-data": "9.19.1",
27
- "@alwatr/local-storage": "9.16.0",
28
- "@alwatr/page-ready": "9.20.0",
29
- "@alwatr/render-state": "9.16.0",
30
- "@alwatr/session-storage": "9.16.0",
31
- "@alwatr/signal": "9.20.0",
24
+ "@alwatr/action": "9.20.1",
25
+ "@alwatr/directive": "9.20.1",
26
+ "@alwatr/embedded-data": "9.21.0",
27
+ "@alwatr/local-storage": "9.20.1",
28
+ "@alwatr/page-ready": "9.20.1",
29
+ "@alwatr/render-state": "9.20.1",
30
+ "@alwatr/session-storage": "9.20.1",
31
+ "@alwatr/signal": "9.20.1",
32
32
  "@alwatr/type-helper": "9.14.0",
33
33
  "lit-html": "^3.3.2"
34
34
  },
@@ -83,5 +83,5 @@
83
83
  "ui",
84
84
  "unidirectional-data-flow"
85
85
  ],
86
- "gitHead": "6e47fd80a2da33bb78e12b1d51258f11e2caec72"
86
+ "gitHead": "40e9e1a2e6f5b6a6f769beb1cc70e518129db32e"
87
87
  }