@alwatr/action 9.14.0 → 9.16.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Declarative DOM action-dispatch — the Action layer for Unidirectional Data Flow.**
4
4
 
5
- `@alwatr/action` bridges HTML `on-action` attributes to typed signal handlers using **global event delegation**. One listener on `document.body` covers every element on the page — including elements added dynamically after bootstrap — with O(1) initialization cost regardless of how many elements exist.
5
+ `@alwatr/action` bridges HTML `on-<eventType>` attributes to typed signal handlers using **global event delegation**. One listener on `document.body` covers every element on the page — including elements added dynamically after bootstrap — with O(1) initialization cost regardless of how many elements exist.
6
6
 
7
7
  ---
8
8
 
@@ -25,7 +25,7 @@ The action bus is powered by a [`ChannelSignal`](../signal/README.md) from `@alw
25
25
 
26
26
  ### Global Event Delegation
27
27
 
28
- A single capture-phase listener on `document.body` handles all `on-action` elements. When an event fires, the handler walks up from `event.target` using `closest('[on-action]')`, parses the attribute, runs modifiers, resolves the payload, and dispatches the action.
28
+ A single capture-phase listener on `document.body` handles all `on-<eventType>` elements. When an event fires, the handler walks up from `event.target` using `closest('[on-click]')` (or the matching attribute), parses the attribute value, runs modifiers, resolves the payload, and dispatches the action.
29
29
 
30
30
  ```
31
31
  User clicks a button
@@ -33,13 +33,13 @@ User clicks a button
33
33
 
34
34
  document.body capture listener (1 listener per event type)
35
35
 
36
- └─ closest('[on-action^=click]') → finds element
37
- parse attribute → 'click->add-to-cart:42'
36
+ └─ closest('[on-click]') → finds element
37
+ parse attribute → 'add_to_cart:42'
38
38
  run modifiers → none
39
39
  resolve payload → '42'
40
- internalChannel_.dispatch('add-to-cart', '42')
40
+ internalChannel_.dispatch('add_to_cart', '42')
41
41
 
42
- └─ Map.get('add-to-cart') → O(1) → invoke only matching handlers
42
+ └─ Map.get('add_to_cart') → O(1) → invoke only matching handlers
43
43
  ```
44
44
 
45
45
  ### Complexity
@@ -53,7 +53,7 @@ document.body capture listener (1 listener per event type)
53
53
 
54
54
  ### `once` modifier
55
55
 
56
- In delegation mode, `once` is implemented by removing the `on-action` attribute from the element after the first fire. This is simpler than a `WeakSet` cache and naturally handles element reuse — if the element is re-rendered with the attribute, it fires again.
56
+ In delegation mode, `once` is implemented by removing the `on-<eventType>` attribute from the element after the first fire. This is simpler than a `WeakSet` cache and naturally handles element reuse — if the element is re-rendered with the attribute, it fires again.
57
57
 
58
58
  ---
59
59
 
@@ -77,10 +77,10 @@ Extend `ActionRecord` via declaration merging. This gives you full type safety a
77
77
  // src/action-record.ts
78
78
  declare module '@alwatr/action' {
79
79
  interface ActionRecord {
80
- 'open-drawer': string;
81
- 'search-query': string;
82
- 'add-to-cart': {productId: number; qty: number};
83
- 'logout': void;
80
+ open_drawer: string;
81
+ search_query: string;
82
+ add_to_cart: {productId: number; qty: number};
83
+ logout: void;
84
84
  }
85
85
  }
86
86
  ```
@@ -94,8 +94,8 @@ import './action-record.js'; // ensure the declaration is loaded
94
94
  setupActionDelegation();
95
95
 
96
96
  // Payload types are inferred from ActionRecord — no generics needed.
97
- onAction('open-drawer', (panel) => openDrawer(panel)); // panel: string
98
- onAction('add-to-cart', (item) => {
97
+ onAction('open_drawer', (panel) => openDrawer(panel)); // panel: string
98
+ onAction('add_to_cart', (item) => {
99
99
  cartService.add(item.productId, item.qty); // fully typed
100
100
  });
101
101
  ```
@@ -103,19 +103,22 @@ onAction('add-to-cart', (item) => {
103
103
  ### 3. Add attributes to HTML
104
104
 
105
105
  ```html
106
- <!-- Dispatches 'open-drawer' with payload 'main' on click -->
107
- <button on-action="click->open-drawer:main">Open Drawer</button>
106
+ <!-- Dispatches 'close_drawer' on click no payload -->
107
+ <button on-click="close_drawer">Close</button>
108
108
 
109
- <!-- Dispatches 'search-query' with the input's live value -->
109
+ <!-- Dispatches 'open_drawer' with payload 'main' on click -->
110
+ <button on-click="open_drawer:main">Open Drawer</button>
111
+
112
+ <!-- Dispatches 'search_query' with the input's live value -->
110
113
  <input
111
114
  type="search"
112
- on-action="input->search-query:$value"
115
+ on-input="search_query:$value"
113
116
  placeholder="Search…"
114
117
  />
115
118
 
116
119
  <!-- Prevents default, validates, then dispatches all field values -->
117
120
  <form
118
- on-action="submit.prevent.validate->submit-form:$formdata"
121
+ on-submit="submit_form:$formdata; prevent,validate"
119
122
  novalidate
120
123
  >
121
124
  <input
@@ -126,7 +129,7 @@ onAction('add-to-cart', (item) => {
126
129
  </form>
127
130
 
128
131
  <!-- Fires only once — attribute is removed after first click -->
129
- <button on-action="click.once->welcome-dismissed">Got it</button>
132
+ <button on-click="welcome_dismissed; once">Got it</button>
130
133
  ```
131
134
 
132
135
  ### 4. Programmatic dispatch
@@ -135,7 +138,7 @@ onAction('add-to-cart', (item) => {
135
138
  import {dispatchAction} from '@alwatr/action';
136
139
 
137
140
  await uploadFile(file);
138
- dispatchAction('upload-complete', fileId);
141
+ dispatchAction('upload_complete', fileId);
139
142
 
140
143
  dispatchAction('navigate', '/dashboard');
141
144
  ```
@@ -145,23 +148,23 @@ dispatchAction('navigate', '/dashboard');
145
148
  ## Attribute Syntax
146
149
 
147
150
  ```
148
- on-action="eventType[.modifier…]->actionId[:payload]"
151
+ on-<eventType>="actionId[:payload][; modifier1,modifier2,…]"
149
152
  ```
150
153
 
151
- | Segment | Description | Example |
152
- | ----------- | --------------------------------------------------------- | ----------------------------- |
153
- | `eventType` | Any standard DOM event name | `click`, `input`, `submit` |
154
- | `modifier` | Optional dot-chained tokens processed before dispatch | `.prevent`, `.validate` |
155
- | `actionId` | Identifier your handler subscribes to | `open-drawer`, `search-query` |
156
- | `:payload` | Optional literal string, or a `$`-prefixed resolver token | `:main`, `:$value` |
154
+ | Segment | Description | Example |
155
+ | ------------- | ----------------------------------------------------------- | ----------------------------- |
156
+ | `eventType` | Any standard DOM event name — encoded in the attribute name | `on-click`, `on-submit` |
157
+ | `actionId` | Identifier your handler subscribes to | `open_drawer`, `search_query` |
158
+ | `:payload` | Optional literal string, or a `$`-prefixed resolver token | `:main`, `:$value` |
159
+ | `; modifiers` | Optional comma-separated modifier list after a semicolon | `; prevent,validate` |
157
160
 
158
161
  ### Built-in modifiers
159
162
 
160
- | Modifier | Behavior |
161
- | ----------- | -------------------------------------------------------------------------------- |
162
- | `.prevent` | Calls `event.preventDefault()` |
163
- | `.once` | Removes the `on-action` attribute after first fire — action dispatches only once |
164
- | `.validate` | Cancels dispatch if the nearest `<form>` fails `checkValidity()` |
163
+ | Modifier | Behavior |
164
+ | ---------- | ------------------------------------------------------------------------------------- |
165
+ | `prevent` | Calls `event.preventDefault()` |
166
+ | `once` | Removes the `on-<eventType>` attribute after first fire — action dispatches only once |
167
+ | `validate` | Cancels dispatch if the nearest `<form>` fails `checkValidity()` |
165
168
 
166
169
  ### Built-in payload resolvers
167
170
 
@@ -181,8 +184,8 @@ The global action type registry. Extend via declaration merging to register type
181
184
  ```ts
182
185
  declare module '@alwatr/action' {
183
186
  interface ActionRecord {
184
- 'open-drawer': string;
185
- 'logout': void;
187
+ open_drawer: string;
188
+ logout: void;
186
189
  }
187
190
  }
188
191
  ```
@@ -229,7 +232,7 @@ function onAction<K extends keyof ActionRecord>(
229
232
  ```
230
233
 
231
234
  ```ts
232
- const sub = onAction('open-drawer', (panel) => openDrawer(panel));
235
+ const sub = onAction('open_drawer', (panel) => openDrawer(panel));
233
236
  sub.unsubscribe(); // prevent memory leaks
234
237
  ```
235
238
 
@@ -241,7 +244,7 @@ Dispatches a named action. Payload type is enforced by `ActionRecord`.
241
244
 
242
245
  ```ts
243
246
  // With payload
244
- dispatchAction('open-drawer', 'settings');
247
+ dispatchAction('open_drawer', 'settings');
245
248
 
246
249
  // Void payload — no second argument
247
250
  dispatchAction('logout');
@@ -258,15 +261,14 @@ Handler signature: `(event: Event, element: HTMLElement) => boolean`
258
261
  ```ts
259
262
  import {registerModifier} from '@alwatr/action';
260
263
 
261
- // Arrow function no `this` binding needed
262
- registerModifier('not-disabled', (_event, element) => {
264
+ registerModifier('not_disabled', (_event, element) => {
263
265
  return !(element as HTMLButtonElement).disabled;
264
266
  });
265
267
  ```
266
268
 
267
269
  ```html
268
270
  <button
269
- on-action="click.not-disabled->select-item:$data-id"
271
+ on-click="select_item:$data_id; not_disabled"
270
272
  data-id="42"
271
273
  >
272
274
  Select
@@ -288,7 +290,7 @@ registerPayloadResolver('$checked', (_event, element) => {
288
290
  return (element as HTMLInputElement).checked;
289
291
  });
290
292
 
291
- registerPayloadResolver('$data-id', (_event, element) => {
293
+ registerPayloadResolver('$data_id', (_event, element) => {
292
294
  return (element as HTMLElement).dataset.id ?? null;
293
295
  });
294
296
  ```
@@ -296,10 +298,10 @@ registerPayloadResolver('$data-id', (_event, element) => {
296
298
  ```html
297
299
  <input
298
300
  type="checkbox"
299
- on-action="change->toggle-feature:$checked"
301
+ on-change="toggle_feature:$checked"
300
302
  />
301
303
  <li
302
- on-action="click->select-item:$data-id"
304
+ on-click="select_item:$data_id"
303
305
  data-id="42"
304
306
  >
305
307
  Item
@@ -311,33 +313,33 @@ registerPayloadResolver('$data-id', (_event, element) => {
311
313
  ## Unidirectional Data Flow
312
314
 
313
315
  ```
314
- ┌─────────────────────────────────────────────────────────┐
315
- UI Layer │
316
- │ <button on-action="click->add-to-cart:42">Add</button>
317
- └────────────────────────┬────────────────────────────────┘
318
- │ DOM event bubbles to body
319
-
320
- ┌─────────────────────────────────────────────────────────┐
321
- Action Layer (@alwatr/action)
322
- │ document.body capture listener (1 per event type)
323
- │ → closest('[on-action]') → parse → modifiers
324
- │ → internalChannel_.dispatch('add-to-cart', '42') [O(1)]│
325
- └────────────────────────┬────────────────────────────────┘
326
- │ O(1) routing via ChannelSignal
327
-
328
- ┌─────────────────────────────────────────────────────────┐
329
- Business Logic Layer │
330
- │ onAction('add-to-cart', (id) => cartService.add(id))
331
- └────────────────────────┬────────────────────────────────┘
332
- │ state update
333
-
334
- ┌─────────────────────────────────────────────────────────┐
335
- State Layer (@alwatr/signal)
336
- │ cartSignal.set(newCartState)
337
- └────────────────────────┬────────────────────────────────┘
338
- │ state flows down to UI
339
-
340
- UI re-renders
316
+ ┌──────────────────────────────────────────────────────────┐
317
+ UI Layer │
318
+ │ <button on-click="add_to_cart:42">Add</button>
319
+ └─────────────────────────┬────────────────────────────────┘
320
+ │ DOM event bubbles to body
321
+
322
+ ┌──────────────────────────────────────────────────────────┐
323
+ Action Layer (@alwatr/action)
324
+ │ document.body capture listener (1 per event type)
325
+ │ → closest('[on-click]') → parse → modifiers
326
+ │ → internalChannel_.dispatch('add_to_cart', '42') [O(1)]
327
+ └─────────────────────────┬────────────────────────────────┘
328
+ │ O(1) routing via ChannelSignal
329
+
330
+ ┌──────────────────────────────────────────────────────────┐
331
+ Business Logic Layer │
332
+ │ onAction('add_to_cart', (id) => cartService.add(id))
333
+ └─────────────────────────┬────────────────────────────────┘
334
+ │ state update
335
+
336
+ ┌──────────────────────────────────────────────────────────┐
337
+ State Layer (@alwatr/signal)
338
+ │ cartSignal.set(newCartState)
339
+ └─────────────────────────┬────────────────────────────────┘
340
+ │ state flows down to UI
341
+
342
+ UI re-renders
341
343
  ```
342
344
 
343
345
  ---
@@ -353,6 +355,36 @@ concern, not a user-interaction action.
353
355
 
354
356
  ## Migration from Previous Versions
355
357
 
358
+ ### Attribute syntax changed
359
+
360
+ The event type is now encoded in the **attribute name** instead of the value, and modifiers are listed after a semicolon instead of dot-chained before the arrow.
361
+
362
+ **Before:**
363
+
364
+ ```html
365
+ <button on-action="click->open_drawer:main">Open</button>
366
+ <form
367
+ on-action="submit.prevent.validate->submit_form:$formdata"
368
+ novalidate
369
+ >
370
+
371
+ </form>
372
+ <button on-action="click.once->welcome_dismissed">Got it</button>
373
+ ```
374
+
375
+ **After:**
376
+
377
+ ```html
378
+ <button on-click="open_drawer:main">Open</button>
379
+ <form
380
+ on-submit="submit_form:$formdata; prevent,validate"
381
+ novalidate
382
+ >
383
+
384
+ </form>
385
+ <button on-click="welcome_dismissed; once">Got it</button>
386
+ ```
387
+
356
388
  ### `ActionContext` removed
357
389
 
358
390
  The `this` context in modifier and resolver handlers changed to explicit parameters:
@@ -360,7 +392,7 @@ The `this` context in modifier and resolver handlers changed to explicit paramet
360
392
  **Before:**
361
393
 
362
394
  ```ts
363
- registerModifier('not-disabled', function () {
395
+ registerModifier('not_disabled', function () {
364
396
  return !(this.element as HTMLButtonElement).disabled;
365
397
  });
366
398
  ```
@@ -368,22 +400,51 @@ registerModifier('not-disabled', function () {
368
400
  **After:**
369
401
 
370
402
  ```ts
371
- registerModifier('not-disabled', (_event, element) => {
403
+ registerModifier('not_disabled', (_event, element) => {
372
404
  return !(element as HTMLButtonElement).disabled;
373
405
  });
374
406
  ```
375
407
 
376
- ### `once` behavior changed
377
-
378
- Previously tracked via `WeakSet`. Now removes the `on-action` attribute after first fire.
379
- Behavior is equivalent for typical use cases.
380
-
381
408
  ### `page-ready` moved to `@alwatr/page-ready`
382
409
 
383
410
  `dispatchPageId` / `onPageReady` are no longer part of this package.
384
411
 
385
412
  ---
386
413
 
414
+ ---
415
+
416
+ ## 🌊 Part of Alwatr Flux
417
+
418
+ `@alwatr/action` is the **Action Layer** of the [Alwatr Flux](https://github.com/Alwatr/alwatr/tree/next/pkg/flux) architecture — a complete Unidirectional Data Flow system for building scalable Progressive Web Applications.
419
+
420
+ ```
421
+ View (HTML on-<event> attributes)
422
+
423
+ Action Layer (@alwatr/action) — global delegation, O(1) routing
424
+
425
+ Controller (business logic via onAction)
426
+
427
+ State Layer (@alwatr/signal) — fine-grained reactivity
428
+
429
+ View (re-render only affected nodes)
430
+ ```
431
+
432
+ `@alwatr/action` is the bridge between the **View** and **Controller** layers. It captures user intent from HTML attributes and routes it to the right handler — without any coupling between the UI and business logic.
433
+
434
+ **The full Flux bundle** (`@alwatr/flux`) includes actions, signals, directives, page-ready, and storage — everything you need to build a complete reactive application from a single import.
435
+
436
+ ```typescript
437
+ // Use @alwatr/flux for the complete architecture
438
+ import {setupActionDelegation, onAction, createStateSignal} from '@alwatr/flux';
439
+
440
+ // Or use @alwatr/action standalone for just the action bus
441
+ import {setupActionDelegation, onAction, dispatchAction} from '@alwatr/action';
442
+ ```
443
+
444
+ → [View the complete Flux documentation](https://github.com/Alwatr/alwatr/tree/next/pkg/flux)
445
+
446
+ ---
447
+
387
448
  ## Contributing
388
449
 
389
450
  Contributions are welcome! Please read our [contribution guidelines](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) before submitting a pull request.
@@ -13,8 +13,8 @@
13
13
  * // In your package: src/action-record.ts
14
14
  * declare module '@alwatr/action' {
15
15
  * interface ActionRecord {
16
- * 'open-drawer': string;
17
- * 'add-to-cart': {productId: number; qty: number};
16
+ * 'open_drawer': string;
17
+ * 'add_to_cart': {productId: number; qty: number};
18
18
  * 'logout': void;
19
19
  * }
20
20
  * }
@@ -42,8 +42,8 @@
42
42
  * // pkg/my-feature/src/action-record.ts
43
43
  * declare module '@alwatr/action' {
44
44
  * interface ActionRecord {
45
- * 'open-drawer': string;
46
- * 'add-to-cart': {productId: number; qty: number};
45
+ * 'open_drawer': string;
46
+ * 'add_to_cart': {productId: number; qty: number};
47
47
  * 'logout': void;
48
48
  * }
49
49
  * }
@@ -10,12 +10,12 @@
10
10
  * time — O(N) initialization cost, O(N) memory for listener references, and
11
11
  * zero support for elements added after bootstrap.
12
12
  *
13
- * This module implements the **Qwik-inspired global delegation** pattern:
13
+ * This module implements the global delegation pattern:
14
14
  * - A single listener per event type is attached to `document.body` with
15
15
  * `capture: true` (so it fires even for non-bubbling events).
16
16
  * - When an event fires, the handler walks up the DOM from `event.target`
17
- * using `closest()` to find the nearest element with an `on-action`
18
- * attribute whose event type matches.
17
+ * using `closest()` to find the nearest element with an `on-<eventType>`
18
+ * attribute (e.g. `on-click`, `on-submit`).
19
19
  * - Modifiers and payload resolvers run in the same pipeline as before.
20
20
  * - `dispatchAction` is called with the resolved payload.
21
21
  *
@@ -35,7 +35,7 @@
35
35
  * - `stop` stops further bubbling but the delegation handler has already
36
36
  * captured the event at `body` level — it does not prevent other delegation
37
37
  * handlers from running on the same element.
38
- * - `once` is emulated by delete attribute elements after first fire.
38
+ * - `once` is emulated by removing the attribute after first fire.
39
39
  */
40
40
  /**
41
41
  * Default DOM event types that cover the vast majority of interactive elements.
@@ -50,11 +50,11 @@
50
50
  */
51
51
  export declare const DEFAULT_DELEGATED_EVENTS: readonly string[];
52
52
  /**
53
- * Registers global event delegation for `on-action` attributes.
53
+ * Registers global event delegation for `on-<eventType>` attributes.
54
54
  *
55
55
  * Attaches a single `capture`-phase listener on `document.body` for each
56
- * event type in `eventTypes`. All `on-action` processing — modifier execution,
57
- * payload resolution, and `dispatchAction` — happens inside that one handler.
56
+ * event type in `eventTypes`. All processing — modifier execution, payload
57
+ * resolution, and `dispatchAction` — happens inside that one handler.
58
58
  *
59
59
  * **Call this once at application bootstrap**, before any user interaction.
60
60
  * Subsequent calls with the same event types are no-ops (idempotent).
@@ -80,7 +80,7 @@ export declare const DEFAULT_DELEGATED_EVENTS: readonly string[];
80
80
  * // One call activates the entire page.
81
81
  * setupActionDelegation();
82
82
  *
83
- * onAction('open-drawer', (panel) => openDrawer(panel));
83
+ * onAction('open_drawer', (panel) => openDrawer(panel));
84
84
  * ```
85
85
  *
86
86
  * @example — with extra event types
@@ -1 +1 @@
1
- {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../src/delegate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAoMH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,GAAE,SAAS,MAAM,EAA6B,GAAG,IAAI,CASpG;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAO/C"}
1
+ {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../src/delegate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AA8LH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAElG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,GAAE,SAAS,MAAM,EAA6B,GAAG,IAAI,CASpG;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAO/C"}
package/dist/main.d.ts CHANGED
@@ -1,17 +1,29 @@
1
1
  /**
2
2
  * @alwatr/action — Declarative DOM action-dispatch for Unidirectional Data Flow.
3
3
  *
4
- * ## Activating `on-action` attributes
4
+ * ## Activating `on-<eventType>` attributes
5
5
  *
6
6
  * Call `setupActionDelegation()` once at bootstrap. A single capture-phase
7
- * listener on `document.body` handles every `on-action` element — including
8
- * elements added dynamically after bootstrap — with O(1) initialization cost.
7
+ * listener on `document.body` handles every `on-click`, `on-submit`, etc. element —
8
+ * including elements added dynamically after bootstrap — with O(1) initialization cost.
9
9
  *
10
10
  * ```ts
11
11
  * import {setupActionDelegation, onAction} from '@alwatr/action';
12
12
  *
13
13
  * setupActionDelegation();
14
- * onAction('open-drawer', (panel) => openDrawer(panel));
14
+ * onAction('open_drawer', (panel) => openDrawer(panel));
15
+ * ```
16
+ *
17
+ * ## Attribute syntax
18
+ *
19
+ * ```
20
+ * on-<eventType>="actionId[:payload][; modifier1,modifier2,…]"
21
+ * ```
22
+ *
23
+ * ```html
24
+ * <button on-click="open_drawer:main">Open</button>
25
+ * <input on-input="search_query:$value" />
26
+ * <form on-submit="submit_form:$formdata; prevent,validate" novalidate>…</form>
15
27
  * ```
16
28
  *
17
29
  * ## Programmatic dispatch
@@ -30,8 +42,8 @@
30
42
  * // src/action-record.ts
31
43
  * declare module '@alwatr/action' {
32
44
  * interface ActionRecord {
33
- * 'open-drawer': string;
34
- * 'add-to-cart': {productId: number; qty: number};
45
+ * 'open_drawer': string;
46
+ * 'add_to_cart': {productId: number; qty: number};
35
47
  * 'logout': void;
36
48
  * }
37
49
  * }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,YAAY,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,YAAY,EAAC,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
- /* 📦 @alwatr/action v9.14.0 */
2
- import{createLogger as U}from"@alwatr/logger";import{createChannelSignal as w}from"@alwatr/signal";var D=U("alwatr-action"),Z=w({name:"alwatr-action"});var N=new Map,Q=new Map;N.set("prevent",(q)=>{return q.preventDefault(),!0});N.set("validate",(q,z)=>{let G=z instanceof HTMLFormElement?z:z.closest("form");if(!G)return!1;return G.checkValidity()});Q.set("$value",(q,z)=>{return"value"in z?z.value:null});Q.set("$formdata",(q,z)=>{let G=z instanceof HTMLFormElement?z:z.closest("form");return G?Object.fromEntries(new FormData(G).entries()):null});function R(q,z){return D.logMethodArgs?.("onAction",{actionId:q}),Z.on(q,z)}function k(...q){let[z,G]=q;D.logMethodArgs?.("dispatchAction",{actionId:z,actionPayload:G}),Z.dispatch(z,G)}function E(q,z){if(D.logMethodArgs?.("registerModifier",{name:q}),N.has(q))D.accident("registerModifier","modifier_already_registered",{name:q});N.set(q,z)}function V(q,z){if(D.logMethodArgs?.("registerPayloadResolver",{name:q}),Q.has(q))D.accident("registerPayloadResolver","payload_resolver_already_registered",{name:q});Q.set(q,z)}var x=/^([a-z0-9.-]+)->([a-z0-9-]+)(?::(.+))?$/,X=new Map;function B(q){D.logMethodArgs?.("parseDescriptor__",{attributeValue:q});let z=X.get(q);if(z!==void 0)return z;let G=q.match(x);if(!G)return D.accident("parseDescriptor__","invalid_syntax",{attributeValue:q}),X.set(q,null),null;let[S,...F]=G[1].split(".");if(!S)return D.accident("parseDescriptor__","missing_event_type",{attributeValue:q}),X.set(q,null),null;let J=new Set(F),W=G[2],K=G[3],Y={eventType:S,modifiers:J,actionId:W,payload:K};return X.set(q,Y),Y}var M="on-action";function O(q){let z=q.type;D.logMethodArgs?.("handleDelegatedEvent__",{eventType:z});let G=q.target;if(!G)return;let S=G.closest?.(`[${M}^=${z}]`);if(!S)return;let F=S.getAttribute?.(M)?.trim();if(!F){D.accident("handleDelegatedEvent__","empty_attribute",{eventType:z,attributeValue:F,actionElement:S});return}if(!(S instanceof HTMLElement)){D.accident("handleDelegatedEvent__","target_not_html_element",{eventType:z,attributeValue:F,actionElement:S});return}let J=B(F);if(!J){D.accident("handleDelegatedEvent__","invalid_attribute",{eventType:z,attributeValue:F,actionElement:S});return}if(J.eventType!==z)return;if(D.logMethodArgs?.("handleDelegatedEvent__.action",J),J.modifiers.has("once"))S.removeAttribute(M),X.delete(F);for(let K of J.modifiers){if(K==="once")continue;let Y=N.get(K);if(!Y){D.accident("handleDelegatedEvent__","unknown_modifier",{modifier:K,attributeValue:F});return}if(Y(q,S)===!1)return}let W=J.payload;if(W){let K=Q.get(W);if(K)W=K(q,S)}Z.dispatch(J.actionId,W)}var H=new Set,P=["click","submit","input","change"];function y(q=P){D.logMethodArgs?.("setupActionDelegation",{eventTypes:q});for(let z of q){if(H.has(z))continue;H.add(z),document.body.addEventListener(z,O,{capture:!0})}}function p(){D.logMethod?.("teardownActionDelegation");for(let q of H)document.body.removeEventListener(q,O,{capture:!0});H.clear(),X.clear()}export{p as teardownActionDelegation,y as setupActionDelegation,V as registerPayloadResolver,E as registerModifier,R as onAction,k as dispatchAction,P as DEFAULT_DELEGATED_EVENTS};
1
+ /* 📦 @alwatr/action v9.16.0 */
2
+ import{createLogger as U}from"@alwatr/logger";import{createChannelSignal as W}from"@alwatr/signal";var F=U("alwatr-action"),Y=W({name:"alwatr-action"});var N=new Map,J=new Map;N.set("prevent",(D)=>{return D.preventDefault(),!0});N.set("validate",(D,q)=>{let z=q instanceof HTMLFormElement?q:q.closest("form");if(!z)return!1;return z.checkValidity()});J.set("$value",(D,q)=>{return"value"in q?q.value:null});J.set("$formdata",(D,q)=>{let z=q instanceof HTMLFormElement?q:q.closest("form");return z?Object.fromEntries(new FormData(z)):null});J.set("$checked",(D,q)=>{return"checked"in q?q.checked:null});function E(D,q){return F.logMethodArgs?.("onAction",{actionId:D}),Y.on(D,q)}function R(...D){let[q,z]=D;F.logMethodArgs?.("dispatchAction",{actionId:q,actionPayload:z}),Y.dispatch(q,z)}function V(D,q){if(F.logMethodArgs?.("registerModifier",{name:D}),N.has(D))F.accident("registerModifier","modifier_already_registered",{name:D});N.set(D,q)}function f(D,q){if(F.logMethodArgs?.("registerPayloadResolver",{name:D}),J.has(D))F.accident("registerPayloadResolver","payload_resolver_already_registered",{name:D});J.set(D,q)}var B=/^([a-z0-9_-]+)(?::([^;]+))?(?:;\s*([a-z0-9_,-]+))?$/,Z=new Map;function L(D){F.logMethodArgs?.("parseDescriptor__",{attributeValue:D});let q=Z.get(D);if(q!==void 0)return q;let z=D.match(B);if(!z)return F.accident("parseDescriptor__","invalid_syntax",{attributeValue:D}),Z.set(D,null),null;let X=z[1],G=z[2],O=z[3],K={modifiers:O?new Set(O.split(",").filter(Boolean)):new Set,actionId:X,payload:G};return Z.set(D,K),K}function M(D){let q=D.type;F.logMethodArgs?.("handleDelegatedEvent__",{eventType:q});let z=D.target;if(!z)return;let X=`on-${q}`,G=z.closest?.(`[${X}]`);if(!G)return;let O=G.getAttribute?.(X)?.trim();if(!O){F.accident("handleDelegatedEvent__","empty_attribute",{eventType:q,actionElement:G});return}if(!(G instanceof HTMLElement)){F.accident("handleDelegatedEvent__","target_not_html_element",{eventType:q,actionElement:G});return}let w=L(O);if(!w)return;if(F.logMethodArgs?.("handleDelegatedEvent__.action",{eventType:q,descriptor:w}),w.modifiers.has("once"))G.removeAttribute(X);for(let Q of w.modifiers){if(Q==="once")continue;let H=N.get(Q);if(!H){F.accident("handleDelegatedEvent__","unknown_modifier",{eventType:q,modifier:Q,attributeValue:O,descriptor:w});return}if(H(D,G)===!1)return}let K=w.payload;if(K){let Q=J.get(K);if(Q)K=Q(D,G)}Y.dispatch(w.actionId,K)}var A=new Set,S=["click","submit","input","change"];function _(D=S){F.logMethodArgs?.("setupActionDelegation",{eventTypes:D});for(let q of D){if(A.has(q))continue;A.add(q),document.body.addEventListener(q,M,{capture:!0})}}function u(){F.logMethod?.("teardownActionDelegation");for(let D of A)document.body.removeEventListener(D,M,{capture:!0});A.clear(),Z.clear()}export{u as teardownActionDelegation,_ as setupActionDelegation,f as registerPayloadResolver,V as registerModifier,E as onAction,R as dispatchAction,S as DEFAULT_DELEGATED_EVENTS};
3
3
 
4
- //# debugId=7E5E853AFB39285764756E2164756E21
4
+ //# debugId=C5F4214484C292C364756E2164756E21
5
5
  //# sourceMappingURL=main.js.map