@alwatr/action 9.12.0 → 9.14.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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @file delegate.ts
3
+ *
4
+ * Global Event Delegation engine for `@alwatr/action`.
5
+ *
6
+ * ## Why delegation instead of per-element listeners?
7
+ *
8
+ * The classic directive approach attaches one `addEventListener` per element.
9
+ * With 100 buttons on a page, that means 100 listener registrations at boot
10
+ * time — O(N) initialization cost, O(N) memory for listener references, and
11
+ * zero support for elements added after bootstrap.
12
+ *
13
+ * This module implements the **Qwik-inspired global delegation** pattern:
14
+ * - A single listener per event type is attached to `document.body` with
15
+ * `capture: true` (so it fires even for non-bubbling events).
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.
19
+ * - Modifiers and payload resolvers run in the same pipeline as before.
20
+ * - `dispatchAction` is called with the resolved payload.
21
+ *
22
+ * ## Complexity
23
+ *
24
+ * | Metric | Per-element listeners | Global delegation |
25
+ * | --------------- | --------------------- | ----------------- |
26
+ * | Boot time | O(N elements) | O(1) — 1 loop |
27
+ * | Memory | O(N listeners) | O(1) — 1 handler |
28
+ * | Dynamic content | Requires re-bootstrap | Works out-of-box |
29
+ * | `once` modifier | Native option | Manual tracking |
30
+ *
31
+ * ## Trade-offs vs. the directive approach
32
+ *
33
+ * - `passive` is not supported as a per-element option (all delegated listeners
34
+ * are non-passive so that `prevent` can call `preventDefault()`).
35
+ * - `stop` stops further bubbling but the delegation handler has already
36
+ * captured the event at `body` level — it does not prevent other delegation
37
+ * handlers from running on the same element.
38
+ * - `once` is emulated by delete attribute elements after first fire.
39
+ */
40
+ /**
41
+ * Default DOM event types that cover the vast majority of interactive elements.
42
+ *
43
+ * - `click` — buttons, links, checkboxes, custom interactive elements
44
+ * - `submit` — form submission
45
+ * - `input` — live text input, range sliders
46
+ * - `change` — select boxes, checkboxes, radio buttons (fires on commit)
47
+ *
48
+ * Pass additional types to `setupActionDelegation` when your app uses other
49
+ * events (e.g. `'keydown'`, `'pointerup'`).
50
+ */
51
+ export declare const DEFAULT_DELEGATED_EVENTS: readonly string[];
52
+ /**
53
+ * Registers global event delegation for `on-action` attributes.
54
+ *
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.
58
+ *
59
+ * **Call this once at application bootstrap**, before any user interaction.
60
+ * Subsequent calls with the same event types are no-ops (idempotent).
61
+ *
62
+ * ### Why `capture: true`?
63
+ *
64
+ * Capture-phase listeners fire before bubble-phase listeners and also catch
65
+ * events that do not bubble (e.g. `focus`, `blur`). This ensures the delegation
66
+ * handler always runs, even when a child element calls `stopPropagation()`.
67
+ *
68
+ * ### Dynamic content
69
+ *
70
+ * Because the listener lives on `document.body`, any element added to the DOM
71
+ * after this call — via `innerHTML`, `lit-html`, a framework renderer, or
72
+ * server-sent HTML — is automatically covered. No re-bootstrap is needed.
73
+ *
74
+ * @param eventTypes - Event types to delegate. Defaults to `DEFAULT_DELEGATED_EVENTS`.
75
+ *
76
+ * @example — minimal bootstrap
77
+ * ```ts
78
+ * import {setupActionDelegation, onAction} from '@alwatr/action';
79
+ *
80
+ * // One call activates the entire page.
81
+ * setupActionDelegation();
82
+ *
83
+ * onAction('open-drawer', (panel) => openDrawer(panel));
84
+ * ```
85
+ *
86
+ * @example — with extra event types
87
+ * ```ts
88
+ * import {setupActionDelegation, DEFAULT_DELEGATED_EVENTS} from '@alwatr/action';
89
+ *
90
+ * setupActionDelegation([...DEFAULT_DELEGATED_EVENTS, 'keydown', 'pointerup']);
91
+ * ```
92
+ */
93
+ export declare function setupActionDelegation(eventTypes?: readonly string[]): void;
94
+ /**
95
+ * Removes all global delegation listeners registered by `setupActionDelegation`.
96
+ *
97
+ * Useful in test environments where each test needs a clean slate, or in
98
+ * micro-frontend setups where a sub-app is unmounted.
99
+ *
100
+ * After calling this, `setupActionDelegation` can be called again to re-register.
101
+ */
102
+ export declare function teardownActionDelegation(): void;
103
+ //# sourceMappingURL=delegate.d.ts.map
@@ -0,0 +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"}
package/dist/lib.d.ts CHANGED
@@ -1,25 +1,3 @@
1
- /**
2
- * The shape of every payload carried by the internal action signal.
3
- *
4
- * `actionId` identifies which action was dispatched (e.g. `'open-drawer'`).
5
- * `actionPayload` is the optional value attached to the action — defaults to
6
- * `string` but can be narrowed to any type via the generic parameter `T`.
7
- *
8
- * @template T The type of the action payload. Defaults to `string`.
9
- *
10
- * @example
11
- * ```ts
12
- * // Typed payload for a cart action
13
- * const payload: ActionSignalPayload<{productId: number; qty: number}> = {
14
- * actionId: 'add-to-cart',
15
- * actionPayload: {productId: 42, qty: 1},
16
- * };
17
- * ```
18
- */
19
- export interface ActionSignalPayload<T = string> {
20
- actionId: string;
21
- actionPayload?: T;
22
- }
23
1
  /**
24
2
  * Module-scoped logger for `@alwatr/action`.
25
3
  * Scoped to `'alwatr-action'` so log lines are easy to filter in the console.
@@ -28,16 +6,17 @@ export interface ActionSignalPayload<T = string> {
28
6
  */
29
7
  export declare const logger_: import("@alwatr/logger").AlwatrLogger;
30
8
  /**
31
- * The single shared event signal that carries every dispatched action.
9
+ * The action channel a `ChannelSignal` strictly typed by `ActionRecord`.
32
10
  *
33
- * All `ActionDirective` instances write to this signal via `dispatchAction`,
34
- * and all `onAction` subscriptions read from it. Using one central signal keeps
35
- * the pub/sub wiring minimal and makes the action flow easy to trace.
11
+ * Only action names declared in `ActionRecord` (via declaration merging) are
12
+ * accepted at compile time. Passing an unknown action name to `onAction` or
13
+ * `dispatchAction` is a **compile error** there is no string fallback.
36
14
  *
37
- * The payload is typed as `ActionSignalPayload<unknown>` at the signal level;
38
- * individual subscribers narrow the type through the `onAction` generic.
15
+ * Uses `ChannelSignal` for O(1) routing: dispatching action `'A'` performs a
16
+ * single `Map.get('A')` lookup and invokes only the handlers registered for
17
+ * that specific action — never handlers for `'B'`, `'C'`, etc.
39
18
  *
40
19
  * @internal — not part of the public API; use `onAction` / `dispatchAction` instead.
41
20
  */
42
- export declare const internalSignal_: import("@alwatr/signal").EventSignal<ActionSignalPayload<unknown>>;
21
+ export declare const internalChannel_: import("@alwatr/signal").ChannelSignal<Record<string, unknown>>;
43
22
  //# sourceMappingURL=lib.d.ts.map
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,MAAM;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,CAAC,CAAC;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,OAAO,uCAAgC,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,oEAA2E,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,eAAO,MAAM,OAAO,uCAAgC,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,iEAAwE,CAAC"}
package/dist/main.d.ts CHANGED
@@ -1,16 +1,55 @@
1
1
  /**
2
2
  * @alwatr/action — Declarative DOM action-dispatch for Unidirectional Data Flow.
3
3
  *
4
- * Public API surface:
4
+ * ## Activating `on-action` attributes
5
+ *
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.
9
+ *
10
+ * ```ts
11
+ * import {setupActionDelegation, onAction} from '@alwatr/action';
12
+ *
13
+ * setupActionDelegation();
14
+ * onAction('open-drawer', (panel) => openDrawer(panel));
15
+ * ```
16
+ *
17
+ * ## Programmatic dispatch
18
+ *
19
+ * ```ts
20
+ * import {dispatchAction} from '@alwatr/action';
21
+ *
22
+ * dispatchAction('navigate', '/dashboard');
23
+ * ```
24
+ *
25
+ * ## Registering typed actions
26
+ *
27
+ * Extend `ActionRecord` via declaration merging to get full type safety:
28
+ *
29
+ * ```ts
30
+ * // src/action-record.ts
31
+ * declare module '@alwatr/action' {
32
+ * interface ActionRecord {
33
+ * 'open-drawer': string;
34
+ * 'add-to-cart': {productId: number; qty: number};
35
+ * 'logout': void;
36
+ * }
37
+ * }
38
+ * ```
39
+ *
40
+ * ## Public API
41
+ *
42
+ * - `ActionRecord` — extend this interface to register typed actions
43
+ * - `setupActionDelegation` / `teardownActionDelegation` — global delegation lifecycle
44
+ * - `DEFAULT_DELEGATED_EVENTS` — default event types covered by delegation
5
45
  * - `onAction` / `dispatchAction` — subscribe to and dispatch named actions
6
- * - `registerActionDirective` opt-in to `on-action` HTML attribute support
7
- * - `registerPageIdDirective` — opt-in to `page-id` HTML attribute support
8
- * - `registerModifier` / `registerPayloadResolver` — extend the directive syntax
9
- * - `ActionDirective` / `PageIdDirective` — directive classes (advanced use)
10
- * - `ActionSignalPayload` payload type carried by the internal signal
46
+ * - `registerModifier` / `registerPayloadResolver` extend the attribute syntax
47
+ *
48
+ * ## Page identity
49
+ *
50
+ * For page-ready signals in SSG/SSR apps, use `@alwatr/page-ready` instead.
11
51
  */
52
+ export type { ActionRecord } from './action-record.js';
12
53
  export * from './method.js';
13
- export * from './directive.js';
14
- export * from './page-id.js';
15
- export type { ActionSignalPayload } from './lib.js';
54
+ export * from './delegate.js';
16
55
  //# sourceMappingURL=main.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,YAAY,EAAC,mBAAmB,EAAC,MAAM,UAAU,CAAC"}
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"}
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
- /* 📦 @alwatr/action v9.12.0 */
2
- import{createLogger as S}from"@alwatr/logger";import{createEventSignal as V}from"@alwatr/signal";var J=S("alwatr-action"),Y=V({name:"alwatr-action"});var H=new Map,N=new Map;H.set("prevent",(M)=>{return M.preventDefault(),!0});H.set("stop",(M)=>{return M.stopPropagation(),!0});H.set("validate",function(){let M=this.element_ instanceof HTMLFormElement?this.element_:this.element_.closest("form");if(!M)return this.logger_.accident("validate_modifier","no_form_found",{element:this.element_}),!1;return M.checkValidity()});N.set("$value",function(){return"value"in this.element_?this.element_.value:null});N.set("$formdata",function(){let M=this.element_ instanceof HTMLFormElement?this.element_:this.element_.closest("form");return M?Object.fromEntries(new FormData(M).entries()):null});function k(M,q){return J.logMethodArgs?.("onAction",{actionId:M}),Y.subscribe((G)=>{if(G.actionId===M)J.logMethodArgs?.("onAction.invoke",{actionId:M,payload:G.actionPayload}),q(G.actionPayload)})}function X(M,q){J.logMethodArgs?.("dispatchAction",{actionId:M,actionPayload:q}),Y.dispatch({actionId:M,actionPayload:q})}function w(M,q){if(J.logMethodArgs?.("registerModifier",{name:M}),H.has(M))J.accident("registerModifier","modifier_already_registered",{name:M});H.set(M,q)}function D(M,q){if(J.logMethodArgs?.("registerPayloadResolver",{name:M}),N.has(M))J.accident("registerPayloadResolver","payload_resolver_already_registered",{name:M});N.set(M,q)}import{lazyDirective as C,Directive as L}from"@alwatr/directive";var z=/^([a-z0-9.-]+)->([a-z0-9-]+)(?::(.+))?$/;class F extends L{actionContext_;init_(){this.logger_.logMethodArgs?.("init_",{attributeValue:this.attributeValue});let M=this.attributeValue.trim().match(z);if(!M){this.logger_.accident("init_","invalid_syntax",{attributeValue:this.attributeValue});return}let[q,...G]=M[1].split("."),Q=M[2],W=M[3];if(!q){this.logger_.accident("init_","invalid_syntax",{attributeValue:this.attributeValue});return}let K=new Set;for(let U of G){if(!H.has(U)&&U!=="once"&&U!=="passive"){this.logger_.accident("init_","invalid_modifier",{attributeValue:this.attributeValue,modifier:U});return}K.add(U)}if(K.has("prevent")&&K.has("passive"))this.logger_.accident("init_","conflicting_modifiers_prevent_passive",{attributeValue:this.attributeValue});this.actionContext_={eventType:q,modifiers:K,actionId:Q,payload:W};let Z={once:K.has("once"),passive:K.has("passive")&&!K.has("prevent")},B=this.dispatch_.bind(this);this.element_.addEventListener(q,B,Z),this.addDestroyHook(()=>{this.element_.removeEventListener(q,B,Z)})}dispatch_(M){this.logger_.logMethodArgs?.("dispatch_",{eventType:M.type,actionId:this.actionContext_?.actionId});let q=this.actionContext_;for(let Q of q.modifiers){let W=H.get(Q);if(W&&W.call(this,M)===!1)return}let G=q.payload;if(G){let Q=N.get(G);if(Q)G=Q.call(this,M)}X(q.actionId,G)}}var u=C("on-action",F);import{Directive as j,lazyDirective as E}from"@alwatr/directive";class O extends j{init_(){let M=this.attributeValue.trim();if(this.logger_.logMethodArgs?.("init_",{pageId:M}),!M){this.logger_.accident("init_","empty_page_id");return}X("page-ready",M),this.destroy()}}var h=E("page-id",O);export{D as registerPayloadResolver,h as registerPageIdDirective,w as registerModifier,u as registerActionDirective,k as onAction,X as dispatchAction,O as PageIdDirective,F as ActionDirective};
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};
3
3
 
4
- //# debugId=4319B6193869E0EC64756E2164756E21
4
+ //# debugId=7E5E853AFB39285764756E2164756E21
5
5
  //# sourceMappingURL=main.js.map
package/dist/main.js.map CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/lib.ts", "../src/registry.ts", "../src/method.ts", "../src/directive.ts", "../src/page-id.ts"],
3
+ "sources": ["../src/lib.ts", "../src/registry.ts", "../src/method.ts", "../src/delegate.ts"],
4
4
  "sourcesContent": [
5
- "import {createLogger} from '@alwatr/logger';\nimport {createEventSignal} from '@alwatr/signal';\n\n/**\n * The shape of every payload carried by the internal action signal.\n *\n * `actionId` identifies which action was dispatched (e.g. `'open-drawer'`).\n * `actionPayload` is the optional value attached to the action — defaults to\n * `string` but can be narrowed to any type via the generic parameter `T`.\n *\n * @template T The type of the action payload. Defaults to `string`.\n *\n * @example\n * ```ts\n * // Typed payload for a cart action\n * const payload: ActionSignalPayload<{productId: number; qty: number}> = {\n * actionId: 'add-to-cart',\n * actionPayload: {productId: 42, qty: 1},\n * };\n * ```\n */\nexport interface ActionSignalPayload<T = string> {\n actionId: string;\n actionPayload?: T;\n}\n\n/**\n * Module-scoped logger for `@alwatr/action`.\n * Scoped to `'alwatr-action'` so log lines are easy to filter in the console.\n *\n * @internal\n */\nexport const logger_ = createLogger('alwatr-action');\n\n/**\n * The single shared event signal that carries every dispatched action.\n *\n * All `ActionDirective` instances write to this signal via `dispatchAction`,\n * and all `onAction` subscriptions read from it. Using one central signal keeps\n * the pub/sub wiring minimal and makes the action flow easy to trace.\n *\n * The payload is typed as `ActionSignalPayload<unknown>` at the signal level;\n * individual subscribers narrow the type through the `onAction` generic.\n *\n * @internal — not part of the public API; use `onAction` / `dispatchAction` instead.\n */\nexport const internalSignal_ = createEventSignal<ActionSignalPayload<unknown>>({name: 'alwatr-action'});\n",
6
- "import type {ActionDirective} from './directive.js';\n\n// ─── Type Definitions ────────────────────────────────────────────────────────\n\n/**\n * A modifier handler attached to an `on-action` directive.\n *\n * Called with the directive instance as `this` and the triggering DOM `event`.\n * Return `true` to allow the action to proceed, or `false` to cancel it.\n * Returning `false` is the only way a modifier can veto a dispatch.\n *\n * @example\n * ```ts\n * // A modifier that only allows the action when the element is not disabled\n * const notDisabledHandler: ModifierHandler = function () {\n * return !(this.element_ as HTMLButtonElement).disabled;\n * };\n * ```\n */\nexport type ModifierHandler = (this: ActionDirective, event: Event) => boolean;\n\n/**\n * A payload resolver attached to an `on-action` directive.\n *\n * Called with the directive instance as `this` and the triggering DOM `event`\n * at dispatch time. The return value becomes the `actionPayload` of the\n * dispatched action. Use this to compute dynamic payloads from the DOM state.\n *\n * @example\n * ```ts\n * // A resolver that returns the element's dataset id\n * const dataIdResolver: PayloadResolver = function () {\n * return (this.element_ as HTMLElement).dataset.id ?? null;\n * };\n * ```\n */\nexport type PayloadResolver = (this: ActionDirective, event: Event) => unknown;\n\n// ─── Registries ──────────────────────────────────────────────────────────────\n\n/**\n * Registry of all named modifier handlers.\n *\n * Keys are modifier names used in the `on-action` attribute syntax\n * (e.g. `click.prevent->action-id`). Values are `ModifierHandler` functions.\n * Populated at module load with built-in modifiers; extended at runtime via\n * `registerModifier`.\n *\n * @internal\n */\nexport const modifierRegistry = new Map<string, ModifierHandler>();\n\n/**\n * Registry of all named payload resolvers.\n *\n * Keys are resolver tokens used in the `on-action` attribute syntax\n * (e.g. `click->action-id:$value`). Values are `PayloadResolver` functions.\n * Populated at module load with built-in resolvers; extended at runtime via\n * `registerPayloadResolver`.\n *\n * @internal\n */\nexport const payloadRegistry = new Map<string, PayloadResolver>();\n\n// ─── Built-in Modifiers ───────────────────────────────────────────────────────\n\n/**\n * `prevent` — calls `event.preventDefault()` before dispatching.\n *\n * Use it to suppress the browser's default behaviour (e.g. form submission,\n * link navigation, context menu).\n *\n * @example `<form on-action=\"submit.prevent->submit-form\">`\n */\nmodifierRegistry.set('prevent', (event) => {\n event.preventDefault();\n return true;\n});\n\n/**\n * `stop` — calls `event.stopPropagation()` before dispatching.\n *\n * Prevents the event from bubbling further up the DOM tree. Useful when a\n * child element should handle a click without triggering a parent's listener.\n *\n * @example `<button on-action=\"click.stop->select-item:42\">`\n */\nmodifierRegistry.set('stop', (event) => {\n event.stopPropagation();\n return true;\n});\n\n/**\n * `validate` — cancels the dispatch if the nearest `<form>` fails validation.\n *\n * Looks for a `<form>` ancestor (or the element itself if it is a form) and\n * calls `checkValidity()`. If the form is invalid the action is not dispatched,\n * allowing native constraint-validation UI to surface errors. If no form is\n * found the dispatch is also cancelled and an accident is logged.\n *\n * Pair with `.prevent` on `submit` events to avoid page reloads:\n *\n * @example `<form on-action=\"submit.prevent.validate->submit-form\" novalidate>`\n */\nmodifierRegistry.set('validate', function () {\n const form = this.element_ instanceof HTMLFormElement ? this.element_ : this.element_.closest('form');\n if (!form) {\n this.logger_.accident('validate_modifier', 'no_form_found', {element: this.element_});\n return false;\n }\n return form.checkValidity();\n});\n\n// ─── Built-in Payload Resolvers ───────────────────────────────────────────────\n\n/**\n * `$value` — resolves to the element's `.value` property at dispatch time.\n *\n * Works with any element that exposes a `value` property: `<input>`,\n * `<textarea>`, `<select>`. Returns `null` for elements without `.value`.\n *\n * @example `<input on-action=\"input->search-query:$value\" />`\n */\npayloadRegistry.set('$value', function () {\n return 'value' in this.element_ ? (this.element_ as {value: unknown}).value : null;\n});\n\n/**\n * `$formdata` — resolves to a plain object of all fields in the nearest `<form>`.\n *\n * Collects entries via `FormData` and converts them to a `Record<string, FormDataEntryValue>`.\n * Looks for a `<form>` ancestor (or the element itself). Returns `null` when no\n * form is found.\n *\n * @example `<form on-action=\"submit.prevent.validate->submit-form\">`\n * ```ts\n * onAction<Record<string, FormDataEntryValue>>('submit-form', (data) => {\n * console.log(data); // {username: 'ali', password: '…'}\n * });\n * ```\n */\npayloadRegistry.set('$formdata', function () {\n const form = this.element_ instanceof HTMLFormElement ? this.element_ : this.element_.closest('form');\n return form ? Object.fromEntries(new FormData(form).entries()) : null;\n});\n",
7
- "import {internalSignal_, logger_} from './lib.js';\nimport type {SubscribeResult} from '@alwatr/signal';\nimport {modifierRegistry, payloadRegistry, type ModifierHandler, type PayloadResolver} from './registry.js';\n\n// Re-export extension types so consumers can import them from the package root.\nexport type {ModifierHandler, PayloadResolver};\n\n// ─── Core Action API ──────────────────────────────────────────────────────────\n\n/**\n * Subscribes to a named action dispatched anywhere in the application.\n *\n * The handler is invoked every time `dispatchAction(actionId, payload)` is\n * called whether from an `on-action` directive or from code and the\n * `actionId` matches. Multiple subscribers for the same `actionId` are all\n * notified in subscription order.\n *\n * The generic parameter `T` narrows the type of the received payload.\n * Defaults to `string`, which covers the common case of attribute-driven\n * literal payloads.\n *\n * @param actionId - The action identifier to listen for (e.g. `'open-drawer'`).\n * @param handler - Callback invoked with the resolved payload each time the\n * action is dispatched. `payload` is `undefined` when the\n * action was dispatched without a value.\n * @returns A `SubscribeResult` with an `unsubscribe()` method for cleanup.\n *\n * @example — basic string payload\n * ```ts\n * import {onAction} from '@alwatr/action';\n *\n * const sub = onAction('open-drawer', (panel) => {\n * openDrawer(panel); // panel === 'settings'\n * });\n *\n * // Stop listening when the component is destroyed\n * sub.unsubscribe();\n * ```\n *\n * @example typed object payload\n * ```ts\n * import {onAction} from '@alwatr/action';\n *\n * onAction<{productId: number; qty: number}>('add-to-cart', (item) => {\n * cartService.add(item!.productId, item!.qty);\n * });\n * ```\n */\nexport function onAction<T = string>(actionId: string, handler: (payload?: T) => void): SubscribeResult {\n logger_.logMethodArgs?.('onAction', {actionId});\n return internalSignal_.subscribe((signal) => {\n if (signal.actionId === actionId) {\n logger_.logMethodArgs?.('onAction.invoke', {actionId, payload: signal.actionPayload});\n handler(signal.actionPayload as T);\n }\n });\n}\n\n/**\n * Dispatches a named action to all `onAction` subscribers with a matching `actionId`.\n *\n * This is the programmatic counterpart to the `on-action` HTML attribute.\n * Use it when you need to trigger an action from code rather than from a DOM\n * event (e.g. after an async operation completes, or from a service layer).\n *\n * The generic parameter `T` types the payload. Omit it to default to `string`.\n *\n * @param actionId - The action identifier (e.g. `'navigate'`).\n * @param actionPayload - Optional value passed to every matching subscriber.\n *\n * @example — dispatch without payload\n * ```ts\n * import {dispatchAction} from '@alwatr/action';\n *\n * dispatchAction('logout');\n * ```\n *\n * @example — dispatch with a typed payload\n * ```ts\n * import {dispatchAction} from '@alwatr/action';\n *\n * dispatchAction('navigate', '/dashboard');\n * dispatchAction<{code: number}>('show-error', {code: 404});\n * ```\n */\nexport function dispatchAction<T = string>(actionId: string, actionPayload?: T): void {\n logger_.logMethodArgs?.('dispatchAction', {actionId, actionPayload});\n internalSignal_.dispatch({actionId, actionPayload});\n}\n\n// ─── Extension API ────────────────────────────────────────────────────────────\n\n/**\n * Registers a custom modifier that can be used in `on-action` attribute syntax.\n *\n * A modifier is a dot-chained token placed after the event type\n * (e.g. `click.mymod->action-id`). Its handler runs before the payload is\n * resolved and the action is dispatched. Returning `false` cancels the dispatch.\n *\n * Built-in modifiers (`prevent`, `stop`, `validate`, `once`, `passive`) are\n * always available. This function lets you add domain-specific ones.\n *\n * Registering the same name twice logs an accident and overwrites the previous\n * handler — avoid duplicate registrations in production code.\n *\n * @param name - The modifier token (lowercase, no dots or arrows).\n * @param handler - The `ModifierHandler` function bound to the directive instance.\n *\n * @example — a `confirm` modifier that shows a browser dialog\n * ```ts\n * import {registerModifier} from '@alwatr/action';\n *\n * registerModifier('confirm', function () {\n * return window.confirm('Are you sure?');\n * });\n * ```\n * ```html\n * <button on-action=\"click.confirm->delete-item:42\">Delete</button>\n * ```\n */\nexport function registerModifier(name: string, handler: ModifierHandler): void {\n logger_.logMethodArgs?.('registerModifier', {name});\n if (modifierRegistry.has(name)) {\n logger_.accident('registerModifier', 'modifier_already_registered', {name});\n }\n modifierRegistry.set(name, handler);\n}\n\n/**\n * Registers a custom payload resolver that can be used in `on-action` attribute syntax.\n *\n * A payload resolver is a colon-suffixed token in the attribute value\n * (e.g. `click->action-id:$mytoken`). Its function is called at dispatch time\n * with the directive instance as `this` and the DOM event as the argument.\n * The return value becomes the `actionPayload` passed to `onAction` subscribers.\n *\n * Built-in resolvers (`$value`, `$formdata`) are always available. This function\n * lets you add domain-specific ones.\n *\n * Registering the same name twice logs an accident and overwrites the previous\n * resolver — avoid duplicate registrations in production code.\n *\n * @param name - The resolver token (should start with `$` by convention).\n * @param resolver - The `PayloadResolver` function bound to the directive instance.\n *\n * @example — a `$checked` resolver for checkbox state\n * ```ts\n * import {registerPayloadResolver} from '@alwatr/action';\n *\n * registerPayloadResolver('$checked', function () {\n * return (this.element_ as HTMLInputElement).checked;\n * });\n * ```\n * ```html\n * <input type=\"checkbox\" on-action=\"change->toggle-feature:$checked\" />\n * ```\n *\n * @example — a `$dataset-id` resolver for data attributes\n * ```ts\n * registerPayloadResolver('$dataset-id', function () {\n * return (this.element_ as HTMLElement).dataset.id ?? null;\n * });\n * ```\n * ```html\n * <li on-action=\"click->select-item:$dataset-id\" data-id=\"42\">Item</li>\n * ```\n */\nexport function registerPayloadResolver(name: string, resolver: PayloadResolver): void {\n logger_.logMethodArgs?.('registerPayloadResolver', {name});\n if (payloadRegistry.has(name)) {\n logger_.accident('registerPayloadResolver', 'payload_resolver_already_registered', {name});\n }\n payloadRegistry.set(name, resolver);\n}\n",
8
- "import {lazyDirective, Directive} from '@alwatr/directive';\nimport {modifierRegistry, payloadRegistry} from './registry.js';\nimport {dispatchAction} from './method.js';\n\n// ─── Attribute Syntax Parser ──────────────────────────────────────────────────\n\n/**\n * Regex that parses the `on-action` attribute value into its three segments.\n *\n * Full syntax: `eventType[.modifier…]->actionId[:payload]`\n *\n * | Capture group | Matches | Example |\n * | ------------- | ------------------------------------------- | -------------------- |\n * | 1 | Event type + optional dot-chained modifiers | `click.prevent.once` |\n * | 2 | Action identifier | `open-drawer` |\n * | 3 | Optional payload token or literal | `main` / `$value` |\n *\n * @example\n * ```\n * 'click.prevent.once->open-drawer:main' → ['click.prevent.once', 'open-drawer', 'main']\n * 'input->search-query:$value' → ['input', 'search-query', '$value']\n * 'submit.prevent->submit-form' → ['submit.prevent', 'submit-form', undefined]\n * ```\n */\nconst syntaxRegex = /^([a-z0-9.-]+)->([a-z0-9-]+)(?::(.+))?$/;\n\n// ─── Directive Class ──────────────────────────────────────────────────────────\n\n/**\n * Directive that bridges a DOM event to a typed action signal.\n *\n * Activated automatically by the `on-action` HTML attribute when\n * `registerActionDirective()` has been called before `bootstrapDirectives()`.\n * You rarely need to reference this class directly.\n *\n * **Attribute syntax**\n * ```\n * on-action=\"eventType[.modifier…]->actionId[:payload]\"\n * ```\n *\n * - `eventType` — any standard DOM event name (e.g. `click`, `input`, `submit`).\n * - `modifier` — dot-chained tokens processed before dispatch\n * (`prevent`, `stop`, `validate`, `once`, `passive`, or custom).\n * - `actionId` — the identifier passed to `onAction` subscribers.\n * - `payload` — an optional literal string or a `$`-prefixed resolver token\n * (e.g. `$value`, `$formdata`, or custom).\n *\n * @example\n * ```html\n * <!-- Dispatches 'open-drawer' with payload 'settings' on click -->\n * <button on-action=\"click->open-drawer:settings\">Settings</button>\n *\n * <!-- Dispatches 'search-query' with the live input value on every keystroke -->\n * <input on-action=\"input->search-query:$value\" />\n *\n * <!-- Prevents default, validates, then dispatches 'submit-form' with all field values -->\n * <form on-action=\"submit.prevent.validate->submit-form:$formdata\" novalidate>…</form>\n * ```\n */\nexport class ActionDirective extends Directive {\n /**\n * Parsed and validated representation of the `on-action` attribute value.\n *\n * Set during `init_()` after the attribute is successfully parsed against\n * `syntaxRegex`. Remains `undefined` when the attribute value is invalid,\n * which prevents `dispatch_` from running.\n */\n protected actionContext_?: {\n /** The DOM event type to listen for (e.g. `'click'`, `'input'`). */\n eventType: string;\n /** Set of active modifier names (e.g. `{'prevent', 'once'}`). */\n modifiers: ReadonlySet<string>;\n /** The action identifier dispatched to `onAction` subscribers. */\n actionId: string;\n /** Raw payload token from the attribute (literal string or `$`-resolver key). */\n payload?: string;\n };\n\n /**\n * Parses the `on-action` attribute, validates modifiers, and attaches the\n * DOM event listener.\n *\n * Called once by `Directive` after one macrotask following element discovery.\n * If the attribute value is malformed or references an unknown modifier,\n * an accident is logged and the directive becomes a no-op.\n */\n protected override init_(): void {\n this.logger_.logMethodArgs?.('init_', {attributeValue: this.attributeValue});\n\n const match = this.attributeValue.trim().match(syntaxRegex);\n\n if (!match) {\n this.logger_.accident('init_', 'invalid_syntax', {attributeValue: this.attributeValue});\n return;\n }\n\n const [eventType, ...modifierList] = match[1].split('.');\n const actionId = match[2];\n const payload = match[3] as string | undefined;\n\n if (!eventType) {\n this.logger_.accident('init_', 'invalid_syntax', {attributeValue: this.attributeValue});\n return;\n }\n\n // Validate every modifier token against the registry (built-in native\n // options 'once' and 'passive' are handled separately by the listener).\n const modifiers = new Set<string>();\n for (const modifier of modifierList) {\n if (!modifierRegistry.has(modifier) && modifier !== 'once' && modifier !== 'passive') {\n this.logger_.accident('init_', 'invalid_modifier', {attributeValue: this.attributeValue, modifier});\n return;\n }\n modifiers.add(modifier);\n }\n\n // 'prevent' and 'passive' are mutually exclusive: a passive listener cannot\n // call preventDefault(). Log an accident but continue — 'prevent' wins.\n if (modifiers.has('prevent') && modifiers.has('passive')) {\n this.logger_.accident('init_', 'conflicting_modifiers_prevent_passive', {attributeValue: this.attributeValue});\n }\n\n this.actionContext_ = {eventType, modifiers, actionId, payload};\n\n // Bind once so the same function reference is used for both add and remove.\n const listenerOptions: AddEventListenerOptions = {\n once: modifiers.has('once'),\n // 'passive' is only meaningful when 'prevent' is absent.\n passive: modifiers.has('passive') && !modifiers.has('prevent'),\n };\n\n const boundDispatch = this.dispatch_.bind(this);\n this.element_.addEventListener(eventType, boundDispatch, listenerOptions);\n // Register cleanup so the listener is removed when the directive is destroyed\n // (e.g. when the element is removed from the DOM via autoDestructDirectives).\n this.addDestroyHook(() => {\n this.element_.removeEventListener(eventType, boundDispatch, listenerOptions);\n });\n }\n\n /**\n * DOM event handler: runs modifiers, resolves the payload, and dispatches\n * the action signal.\n *\n * Execution order:\n * 1. Each modifier in `actionContext_.modifiers` is called in insertion order.\n * If any returns `false` the method returns early — no action is dispatched.\n * 2. The raw payload token is looked up in `payloadRegistry`. If a resolver\n * is found it is called and its return value replaces the token.\n * 3. `dispatchAction` is called with the resolved payload.\n *\n * @param event - The DOM event that triggered this handler.\n */\n protected dispatch_(event: Event): void {\n this.logger_.logMethodArgs?.('dispatch_', {eventType: event.type, actionId: this.actionContext_?.actionId});\n\n const context = this.actionContext_!;\n\n // Step 1 — run modifiers; any returning false cancels the dispatch.\n for (const mod of context.modifiers) {\n const handler = modifierRegistry.get(mod);\n if (handler && handler.call(this, event) === false) return;\n }\n\n // Step 2 — resolve dynamic payload tokens (e.g. '$value', '$formdata').\n let payload: unknown = context.payload;\n if (payload) {\n const resolver = payloadRegistry.get(payload as string);\n if (resolver) payload = resolver.call(this, event);\n }\n\n // Step 3 — dispatch the action to all onAction subscribers.\n dispatchAction(context.actionId, payload);\n }\n}\n\n// ─── Lazy Registration ────────────────────────────────────────────────────────\n\n/**\n * Registers `ActionDirective` under the `on-action` attribute name.\n *\n * This is a **lazy** registration: calling this function is the only way to\n * opt-in to `on-action` support. If it is never called, the entire directive\n * module (including `ActionDirective`) is tree-shaken from the bundle.\n *\n * Call it once, before `bootstrapDirectives()`, at your application entry point.\n *\n * @example\n * ```ts\n * import {registerActionDirective} from '@alwatr/action';\n * import {bootstrapDirectives} from '@alwatr/directive';\n *\n * registerActionDirective();\n * bootstrapDirectives();\n * ```\n */\nexport const registerActionDirective = lazyDirective('on-action', ActionDirective);\n",
9
- "import {Directive, lazyDirective} from '@alwatr/directive';\nimport {dispatchAction} from './method.js';\n\n// ─── Directive Class ──────────────────────────────────────────────────────────\n\n/**\n * Directive that announces the current page identity as an action signal.\n *\n * Activated by the `page-id` HTML attribute. On bootstrap the directive reads\n * the attribute value as the page identifier, dispatches a `'page-ready'`\n * action with that value as the payload, and immediately self-destructs — no\n * persistent listener is registered.\n *\n * Typical placement is on the `<body>` or the top-level page container so that\n * any part of the application can react to route changes by subscribing to the\n * `'page-ready'` action via `onAction`.\n *\n * @example\n * ```html\n * <!-- Dispatches dispatchAction('page-ready', 'home') on bootstrap -->\n * <body page-id=\"home\">…</body>\n * ```\n */\nexport class PageIdDirective extends Directive {\n /**\n * Reads the `page-id` attribute value, dispatches `'page-ready'` with it as\n * the payload, then destroys the directive.\n *\n * Logs an accident and returns early if the attribute value is empty.\n */\n protected override init_(): void {\n const pageId = this.attributeValue.trim();\n this.logger_.logMethodArgs?.('init_', {pageId});\n\n if (!pageId) {\n this.logger_.accident('init_', 'empty_page_id');\n return;\n }\n\n dispatchAction('page-ready', pageId);\n this.destroy();\n }\n}\n\n// ─── Lazy Registration ────────────────────────────────────────────────────────\n\n/**\n * Registers `PageIdDirective` under the `page-id` attribute name.\n *\n * This is a **lazy** registration: calling this function is the only way to\n * opt-in to `page-id` support. If it is never called, the entire directive\n * module is tree-shaken from the bundle.\n *\n * Call it once, before `bootstrapDirectives()`, at your application entry point.\n *\n * @example\n * ```ts\n * import {registerPageIdDirective, onAction} from '@alwatr/action';\n * import {bootstrapDirectives} from '@alwatr/directive';\n *\n * registerPageIdDirective();\n * bootstrapDirectives();\n *\n * // React to every page change\n * onAction('page-ready', (pageId) => {\n * console.log('navigated to:', pageId); // e.g. 'home', 'about', 'product-detail'\n * });\n * ```\n *\n * ```html\n * <body page-id=\"home\">…</body>\n * ```\n */\nexport const registerPageIdDirective = lazyDirective('page-id', PageIdDirective);\n"
5
+ "import {createLogger} from '@alwatr/logger';\nimport {createChannelSignal} from '@alwatr/signal';\n\n/**\n * Module-scoped logger for `@alwatr/action`.\n * Scoped to `'alwatr-action'` so log lines are easy to filter in the console.\n *\n * @internal\n */\nexport const logger_ = createLogger('alwatr-action');\n\n/**\n * The action channel a `ChannelSignal` strictly typed by `ActionRecord`.\n *\n * Only action names declared in `ActionRecord` (via declaration merging) are\n * accepted at compile time. Passing an unknown action name to `onAction` or\n * `dispatchAction` is a **compile error** there is no string fallback.\n *\n * Uses `ChannelSignal` for O(1) routing: dispatching action `'A'` performs a\n * single `Map.get('A')` lookup and invokes only the handlers registered for\n * that specific action never handlers for `'B'`, `'C'`, etc.\n *\n * @internal — not part of the public API; use `onAction` / `dispatchAction` instead.\n */\nexport const internalChannel_ = createChannelSignal<Record<string, unknown>>({name: 'alwatr-action'});\n",
6
+ "// ─── Type Definitions ────────────────────────────────────────────────────────\n\n/**\n * A modifier handler used in `on-action` attribute syntax.\n *\n * Receives the triggering DOM `event` and the `element` that owns the\n * `on-action` attribute. Return `true` (or any truthy value) to allow the\n * action to proceed, or `false` to cancel the dispatch.\n *\n * Using explicit parameters instead of `this` binding makes handlers\n * compatible with arrow functions and easier to test in isolation.\n *\n * @example\n * ```ts\n * // A modifier that only allows the action when the element is not disabled\n * const notDisabledHandler: ModifierHandler = (_event, element) => {\n * return !(element as HTMLButtonElement).disabled;\n * };\n * ```\n */\nexport type ModifierHandler = (event: Event, element: HTMLElement) => boolean;\n\n/**\n * A payload resolver used in `on-action` attribute syntax.\n *\n * Receives the triggering DOM `event` and the `element` that owns the\n * `on-action` attribute. The return value becomes the `actionPayload` passed\n * to `onAction` subscribers. Use this to compute dynamic payloads from DOM state.\n *\n * Using explicit parameters instead of `this` binding makes resolvers\n * compatible with arrow functions and easier to test in isolation.\n *\n * @example\n * ```ts\n * // A resolver that returns the element's dataset id\n * const dataIdResolver: PayloadResolver = (_event, element) => {\n * return (element as HTMLElement).dataset.id ?? null;\n * };\n * ```\n */\nexport type PayloadResolver = (event: Event, element: HTMLElement) => unknown;\n\n// ─── Registries ──────────────────────────────────────────────────────────────\n\n/**\n * Registry of all named modifier handlers.\n *\n * Keys are modifier names used in the `on-action` attribute syntax\n * (e.g. `click.prevent->action-id`). Values are `ModifierHandler` functions.\n * Populated at module load with built-in modifiers; extended at runtime via\n * `registerModifier`.\n *\n * @internal\n */\nexport const modifierRegistry = new Map<string, ModifierHandler>();\n\n/**\n * Registry of all named payload resolvers.\n *\n * Keys are resolver tokens used in the `on-action` attribute syntax\n * (e.g. `click->action-id:$value`). Values are `PayloadResolver` functions.\n * Populated at module load with built-in resolvers; extended at runtime via\n * `registerPayloadResolver`.\n *\n * @internal\n */\nexport const payloadRegistry = new Map<string, PayloadResolver>();\n\n// ─── Built-in Modifiers ───────────────────────────────────────────────────────\n\n/**\n * `prevent` — calls `event.preventDefault()` before dispatching.\n *\n * Use it to suppress the browser's default behaviour (e.g. form submission,\n * link navigation, context menu).\n *\n * @example `<form on-action=\"submit.prevent->submit-form\">`\n */\nmodifierRegistry.set('prevent', (event) => {\n event.preventDefault();\n return true;\n});\n\n/**\n * `validate` — cancels the dispatch if the nearest `<form>` fails validation.\n *\n * Looks for a `<form>` ancestor (or the element itself if it is a form) and\n * calls `checkValidity()`. If the form is invalid the action is not dispatched,\n * allowing native constraint-validation UI to surface errors. If no form is\n * found the dispatch is also cancelled.\n *\n * Pair with `.prevent` on `submit` events to avoid page reloads:\n *\n * @example `<form on-action=\"submit.prevent.validate->submit-form:$formdata\" novalidate>`\n */\nmodifierRegistry.set('validate', (_event, element) => {\n const form = element instanceof HTMLFormElement ? element : element.closest('form');\n if (!form) return false;\n return form.checkValidity();\n});\n\n// ─── Built-in Payload Resolvers ───────────────────────────────────────────────\n\n/**\n * `$value` — resolves to the element's `.value` property at dispatch time.\n *\n * Works with any element that exposes a `value` property: `<input>`,\n * `<textarea>`, `<select>`. Returns `null` for elements without `.value`.\n *\n * @example `<input on-action=\"input->search-query:$value\" />`\n */\npayloadRegistry.set('$value', (_event, element) => {\n return 'value' in element ? (element as {value: unknown}).value : null;\n});\n\n/**\n * `$formdata` — resolves to a plain object of all fields in the nearest `<form>`.\n *\n * Collects entries via `FormData` and converts them to a `Record<string, FormDataEntryValue>`.\n * Looks for a `<form>` ancestor (or the element itself). Returns `null` when no\n * form is found.\n *\n * @example `<form on-action=\"submit.prevent.validate->submit-form:$formdata\">`\n * ```ts\n * onAction('submit-form', (data) => {\n * console.log(data); // {username: 'ali', password: '…'}\n * });\n * ```\n */\npayloadRegistry.set('$formdata', (_event, element) => {\n const form = element instanceof HTMLFormElement ? element : element.closest('form');\n return form ? Object.fromEntries(new FormData(form).entries()) : null;\n});\n",
7
+ "import type {Awaitable} from '@alwatr/type-helper';\nimport {internalChannel_, logger_} from './lib.js';\nimport type {SubscribeResult} from '@alwatr/signal';\nimport {modifierRegistry, payloadRegistry, type ModifierHandler, type PayloadResolver} from './registry.js';\nimport type {ActionRecord} from './action-record.js';\n\n// Re-export extension types so consumers can import them from the package root.\nexport type {ModifierHandler, PayloadResolver};\n\n// ─── Core Action API ──────────────────────────────────────────────────────────\n\n/**\n * Subscribes to a named action dispatched anywhere in the application.\n *\n * `actionId` must be a key of `ActionRecord`. The handler's `payload` parameter\n * is automatically typed to the corresponding `ActionRecord` value no manual\n * generic annotation needed:\n *\n * ```ts\n * // ActionRecord declares: 'add-to-cart': {productId: number; qty: number}\n * onAction('add-to-cart', (item) => {\n * cartService.add(item.productId, item.qty); // fully typed, no `!` needed\n * });\n * ```\n *\n * Passing an action name not declared in `ActionRecord` is a **compile error**.\n * Register new actions by extending `ActionRecord` via declaration merging:\n *\n * ```ts\n * // src/action-record.ts\n * declare module '@alwatr/action' {\n * interface ActionRecord {\n * 'open-drawer': string;\n * }\n * }\n * ```\n *\n * Internally delegates to `ChannelSignal.on()` for **O(1) routing** — dispatching\n * action `'A'` never invokes handlers registered for action `'B'`.\n *\n * @param actionId - A key of `ActionRecord`.\n * @param handler - Callback invoked with the typed payload on each dispatch.\n * @returns A `SubscribeResult` with an `unsubscribe()` method for cleanup.\n *\n * @example\n * ```ts\n * import {onAction} from '@alwatr/action';\n *\n * const sub = onAction('page-ready', (pageId) => {\n * router.setPage(pageId); // pageId: string — inferred from ActionRecord\n * });\n *\n * sub.unsubscribe(); // stop listening when no longer needed\n * ```\n */\nexport function onAction<K extends keyof ActionRecord>(\n actionId: K,\n handler: (payload: ActionRecord[K]) => Awaitable<void>,\n): SubscribeResult {\n logger_.logMethodArgs?.('onAction', {actionId});\n return internalChannel_.on(actionId, handler as (payload: unknown) => Awaitable<void>);\n}\n\n/**\n * Dispatches a named action to all `onAction` subscribers with a matching `actionId`.\n *\n * `actionId` must be a key of `ActionRecord`. The `payload` parameter is\n * automatically typed — passing the wrong type is a **compile error**:\n *\n * ```ts\n * // ActionRecord declares: 'add-to-cart': {productId: number; qty: number}\n * dispatchAction('add-to-cart', {productId: 42, qty: 1}); // ✅\n * dispatchAction('add-to-cart', 'wrong'); // ❌ compile error\n * dispatchAction('unknown-action', 'x'); // ❌ compile error\n * ```\n *\n * Register new actions by extending `ActionRecord` via declaration merging:\n *\n * ```ts\n * // src/action-record.ts\n * declare module '@alwatr/action' {\n * interface ActionRecord {\n * 'navigate': string;\n * 'logout': void;\n * }\n * }\n * ```\n *\n * Use `dispatchAction` when triggering an action from code — e.g. after an\n * async operation, from a service layer, or in tests. For DOM-driven actions,\n * use the `on-action` HTML attribute with `setupActionDelegation`.\n *\n * @param actionId - A key of `ActionRecord`.\n * @param actionPayload - The payload; type is enforced by `ActionRecord`.\n *\n * @example — with payload\n * ```ts\n * import {dispatchAction} from '@alwatr/action';\n *\n * dispatchAction('page-ready', 'home');\n * dispatchAction('navigate', '/dashboard');\n * ```\n *\n * @example — void payload (no second argument)\n * ```ts\n * dispatchAction('logout');\n * ```\n */\nexport function dispatchAction<K extends keyof ActionRecord>(\n ...args: ActionRecord[K] extends void | undefined ? [actionId: K] : [actionId: K, actionPayload: ActionRecord[K]]\n): void {\n const [actionId, actionPayload] = args;\n logger_.logMethodArgs?.('dispatchAction', {actionId, actionPayload});\n internalChannel_.dispatch(actionId, actionPayload);\n}\n\n// ─── Extension API ────────────────────────────────────────────────────────────\n\n/**\n * Registers a custom modifier that can be used in `on-action` attribute syntax.\n *\n * A modifier is a dot-chained token placed after the event type\n * (e.g. `click.mymod->action-id`). Its handler runs before the payload is\n * resolved and the action is dispatched. Returning `false` cancels the dispatch.\n *\n * Built-in modifiers (`prevent`, `stop`, `validate`, `once`) are always\n * available. This function lets you add domain-specific ones.\n *\n * Registering the same name twice logs an accident and overwrites the previous\n * handler — avoid duplicate registrations in production code.\n *\n * @param name - The modifier token (lowercase, no dots or arrows).\n * @param handler - A `ModifierHandler` receiving `(event, element)`.\n *\n * @example — a `confirm` modifier that shows a browser dialog\n * ```ts\n * import {registerModifier} from '@alwatr/action';\n *\n * registerModifier('confirm', () => window.confirm('Are you sure?'));\n * ```\n * ```html\n * <button on-action=\"click.confirm->delete-item:42\">Delete</button>\n * ```\n */\nexport function registerModifier(name: string, handler: ModifierHandler): void {\n logger_.logMethodArgs?.('registerModifier', {name});\n if (modifierRegistry.has(name)) {\n logger_.accident('registerModifier', 'modifier_already_registered', {name});\n }\n modifierRegistry.set(name, handler);\n}\n\n/**\n * Registers a custom payload resolver that can be used in `on-action` attribute syntax.\n *\n * A payload resolver is a colon-suffixed token in the attribute value\n * (e.g. `click->action-id:$mytoken`). Its function is called at dispatch time\n * with an `ActionContext` as `this` and the DOM event as the argument.\n * The return value becomes the `actionPayload` passed to `onAction` subscribers.\n *\n * Built-in resolvers (`$value`, `$formdata`) are always available. This function\n * lets you add domain-specific ones.\n *\n * Registering the same name twice logs an accident and overwrites the previous\n * resolver — avoid duplicate registrations in production code.\n *\n * @param name - The resolver token (should start with `$` by convention).\n * @param resolver - A `PayloadResolver` receiving `(event, element)`.\n *\n * @example — a `$checked` resolver for checkbox state\n * ```ts\n * import {registerPayloadResolver} from '@alwatr/action';\n *\n * registerPayloadResolver('$checked', (_event, element) => {\n * return (element as HTMLInputElement).checked;\n * });\n * ```\n * ```html\n * <input type=\"checkbox\" on-action=\"change->toggle-feature:$checked\" />\n * ```\n */\nexport function registerPayloadResolver(name: string, resolver: PayloadResolver): void {\n logger_.logMethodArgs?.('registerPayloadResolver', {name});\n if (payloadRegistry.has(name)) {\n logger_.accident('registerPayloadResolver', 'payload_resolver_already_registered', {name});\n }\n payloadRegistry.set(name, resolver);\n}\n",
8
+ "/**\n * @file delegate.ts\n *\n * Global Event Delegation engine for `@alwatr/action`.\n *\n * ## Why delegation instead of per-element listeners?\n *\n * The classic directive approach attaches one `addEventListener` per element.\n * With 100 buttons on a page, that means 100 listener registrations at boot\n * time — O(N) initialization cost, O(N) memory for listener references, and\n * zero support for elements added after bootstrap.\n *\n * This module implements the **Qwik-inspired global delegation** pattern:\n * - A single listener per event type is attached to `document.body` with\n * `capture: true` (so it fires even for non-bubbling events).\n * - When an event fires, the handler walks up the DOM from `event.target`\n * using `closest()` to find the nearest element with an `on-action`\n * attribute whose event type matches.\n * - Modifiers and payload resolvers run in the same pipeline as before.\n * - `dispatchAction` is called with the resolved payload.\n *\n * ## Complexity\n *\n * | Metric | Per-element listeners | Global delegation |\n * | --------------- | --------------------- | ----------------- |\n * | Boot time | O(N elements) | O(1) — 1 loop |\n * | Memory | O(N listeners) | O(1) — 1 handler |\n * | Dynamic content | Requires re-bootstrap | Works out-of-box |\n * | `once` modifier | Native option | Manual tracking |\n *\n * ## Trade-offs vs. the directive approach\n *\n * - `passive` is not supported as a per-element option (all delegated listeners\n * are non-passive so that `prevent` can call `preventDefault()`).\n * - `stop` stops further bubbling but the delegation handler has already\n * captured the event at `body` level — it does not prevent other delegation\n * handlers from running on the same element.\n * - `once` is emulated by delete attribute elements after first fire.\n */\n\nimport {internalChannel_, logger_} from './lib.js';\nimport {modifierRegistry, payloadRegistry} from './registry.js';\n\n// ─── Syntax Parser ────────────────────────────────────────────────────────────\n\n/**\n * Parses the `on-action` attribute value into its three segments.\n *\n * Full syntax: `eventType[.modifier…]->actionId[:payload]`\n *\n * | Capture group | Matches | Example |\n * | ------------- | ------------------------------------------- | -------------------- |\n * | 1 | Event type + optional dot-chained modifiers | `click.prevent.once` |\n * | 2 | Action identifier | `open-drawer` |\n * | 3 | Optional payload token or literal | `main` / `$value` |\n *\n * @example\n * ```\n * 'click.prevent.once->open-drawer:main' → ['click.prevent.once', 'open-drawer', 'main']\n * 'input->search-query:$value' → ['input', 'search-query', '$value']\n * 'submit.prevent->submit-form' → ['submit.prevent', 'submit-form', undefined]\n * ```\n */\nconst syntaxRegex = /^([a-z0-9.-]+)->([a-z0-9-]+)(?::(.+))?$/;\n\n// ─── Parsed Action Descriptor ─────────────────────────────────────────────────\n\n/**\n * Parsed and cached representation of a single `on-action` attribute value.\n *\n * Caching avoids re-parsing the same attribute string on every event fire.\n * The cache is keyed by the raw attribute string so identical values share\n * the same descriptor object.\n */\ninterface ActionDescriptor {\n /** The DOM event type to listen for (e.g. `'click'`, `'input'`). */\n readonly eventType: string;\n /** Set of active modifier names (e.g. `{'prevent', 'once'}`). */\n readonly modifiers: ReadonlySet<string>;\n /** The action identifier dispatched to `onAction` subscribers. */\n readonly actionId: string;\n /** Raw payload token from the attribute (literal string or `$`-resolver key). */\n readonly payload: string | undefined;\n}\n\n/**\n * LRU-style cache for parsed `on-action` attribute values.\n *\n * Attribute strings are typically repeated across many elements (e.g. every\n * \"add to cart\" button shares the same `on-action` value). Caching the parsed\n * descriptor avoids redundant regex work on every event.\n *\n * Using a plain `Map` here is intentional — attribute strings are short-lived\n * keys and the map size is bounded by the number of distinct `on-action` values\n * in the page, which is typically small.\n *\n * @internal\n */\nconst descriptorCache__ = new Map<string, ActionDescriptor | null>();\n\n/**\n * Parses an `on-action` attribute value into an `ActionDescriptor`.\n *\n * Returns `null` when the syntax is invalid. Results are cached by the raw\n * attribute string so repeated calls for the same value are O(1).\n *\n * @internal\n */\nfunction parseDescriptor__(attributeValue: string): ActionDescriptor | null {\n logger_.logMethodArgs?.('parseDescriptor__', {attributeValue});\n\n const cached = descriptorCache__.get(attributeValue);\n // Explicit `undefined` check: `null` means \"already parsed and invalid\".\n if (cached !== undefined) return cached;\n\n const match = attributeValue.match(syntaxRegex);\n if (!match) {\n logger_.accident('parseDescriptor__', 'invalid_syntax', {attributeValue});\n descriptorCache__.set(attributeValue, null);\n return null;\n }\n\n const [eventType, ...modifierList] = match[1].split('.');\n if (!eventType) {\n logger_.accident('parseDescriptor__', 'missing_event_type', {attributeValue});\n descriptorCache__.set(attributeValue, null);\n return null;\n }\n\n const modifiers = new Set(modifierList);\n const actionId = match[2];\n const payload: string | undefined = match[3];\n\n const descriptor: ActionDescriptor = {\n eventType,\n modifiers,\n actionId,\n payload,\n };\n\n descriptorCache__.set(attributeValue, descriptor);\n return descriptor;\n}\n\n// ─── Core Delegation Handler ──────────────────────────────────────────────────\n\nconst onActionAttrib__ = 'on-action';\n/**\n * Central event handler attached to `document.body` for every delegated event type.\n *\n * Execution flow for each incoming event:\n * 1. Walk up from `event.target` to find the nearest element with an\n * `on-action` attribute whose event type matches the current event.\n * 2. Parse (or retrieve from cache) the `ActionDescriptor` for that attribute.\n * 3. Run each modifier in order; if any returns `false`, abort.\n * 4. Resolve the payload token (literal or `$`-resolver).\n * 5. Call `dispatchAction(actionId, payload)`.\n *\n * @internal\n */\nfunction handleDelegatedEvent__(event: Event): void {\n const eventType = event.type;\n logger_.logMethodArgs?.('handleDelegatedEvent__', {eventType});\n\n // Walk up the DOM to find the closest element with a matching on-action attribute.\n // We use `closest` on the composedPath target to support Shadow DOM correctly.\n const target = event.target as Element | null;\n if (!target) return;\n\n // Find the nearest ancestor (or self) that has an on-action attribute\n const actionElement = target.closest?.(`[${onActionAttrib__}^=${eventType}]`);\n if (!actionElement) return;\n\n const attributeValue = actionElement.getAttribute?.(onActionAttrib__)?.trim();\n if (!attributeValue) {\n logger_.accident('handleDelegatedEvent__', 'empty_attribute', {eventType, attributeValue, actionElement});\n return;\n }\n\n if (!(actionElement instanceof HTMLElement)) {\n logger_.accident('handleDelegatedEvent__', 'target_not_html_element', {eventType, attributeValue, actionElement});\n return;\n }\n\n const descriptor = parseDescriptor__(attributeValue);\n if (!descriptor) {\n logger_.accident('handleDelegatedEvent__', 'invalid_attribute', {eventType, attributeValue, actionElement});\n return;\n }\n\n if (descriptor.eventType !== eventType) return;\n\n logger_.logMethodArgs?.('handleDelegatedEvent__.action', descriptor);\n\n // Step 1: handle once modifier\n if (descriptor.modifiers.has('once')) {\n actionElement.removeAttribute(onActionAttrib__); // remove on-action to prevent repeat the action\n descriptorCache__.delete(attributeValue); // free memory for once\n }\n\n // Step 2: run modifiers\n for (const modifier of descriptor.modifiers) {\n if (modifier === 'once') continue; // handled separately\n const handler = modifierRegistry.get(modifier);\n if (!handler) {\n logger_.accident('handleDelegatedEvent__', 'unknown_modifier', {modifier, attributeValue});\n return; // unknown modifier — abort to avoid silent misbehaviour\n }\n if (handler(event, actionElement) === false) return;\n }\n\n // Step 3: resolve payload\n let payload: unknown = descriptor.payload;\n if (payload) {\n const resolver = payloadRegistry.get(payload as string);\n if (resolver) payload = resolver(event, actionElement);\n }\n\n // Step 4: dispatch\n internalChannel_.dispatch(descriptor.actionId, payload);\n}\n\n// ─── Setup ────────────────────────────────────────────────────────────────────\n\n/**\n * The set of event types currently delegated to `document.body`.\n *\n * Tracked so that `setupActionDelegation` is idempotent — calling it multiple\n * times with the same event types does not register duplicate listeners.\n *\n * @internal\n */\nconst delegatedEventTypes__ = new Set<string>();\n\n/**\n * Default DOM event types that cover the vast majority of interactive elements.\n *\n * - `click` — buttons, links, checkboxes, custom interactive elements\n * - `submit` — form submission\n * - `input` — live text input, range sliders\n * - `change` — select boxes, checkboxes, radio buttons (fires on commit)\n *\n * Pass additional types to `setupActionDelegation` when your app uses other\n * events (e.g. `'keydown'`, `'pointerup'`).\n */\nexport const DEFAULT_DELEGATED_EVENTS: readonly string[] = ['click', 'submit', 'input', 'change'];\n\n/**\n * Registers global event delegation for `on-action` attributes.\n *\n * Attaches a single `capture`-phase listener on `document.body` for each\n * event type in `eventTypes`. All `on-action` processing — modifier execution,\n * payload resolution, and `dispatchAction` — happens inside that one handler.\n *\n * **Call this once at application bootstrap**, before any user interaction.\n * Subsequent calls with the same event types are no-ops (idempotent).\n *\n * ### Why `capture: true`?\n *\n * Capture-phase listeners fire before bubble-phase listeners and also catch\n * events that do not bubble (e.g. `focus`, `blur`). This ensures the delegation\n * handler always runs, even when a child element calls `stopPropagation()`.\n *\n * ### Dynamic content\n *\n * Because the listener lives on `document.body`, any element added to the DOM\n * after this call — via `innerHTML`, `lit-html`, a framework renderer, or\n * server-sent HTML — is automatically covered. No re-bootstrap is needed.\n *\n * @param eventTypes - Event types to delegate. Defaults to `DEFAULT_DELEGATED_EVENTS`.\n *\n * @example — minimal bootstrap\n * ```ts\n * import {setupActionDelegation, onAction} from '@alwatr/action';\n *\n * // One call activates the entire page.\n * setupActionDelegation();\n *\n * onAction('open-drawer', (panel) => openDrawer(panel));\n * ```\n *\n * @example — with extra event types\n * ```ts\n * import {setupActionDelegation, DEFAULT_DELEGATED_EVENTS} from '@alwatr/action';\n *\n * setupActionDelegation([...DEFAULT_DELEGATED_EVENTS, 'keydown', 'pointerup']);\n * ```\n */\nexport function setupActionDelegation(eventTypes: readonly string[] = DEFAULT_DELEGATED_EVENTS): void {\n logger_.logMethodArgs?.('setupActionDelegation', {eventTypes});\n\n for (const eventType of eventTypes) {\n if (delegatedEventTypes__.has(eventType)) continue; // already registered — skip\n delegatedEventTypes__.add(eventType);\n // capture: true — fires before bubble-phase listeners and catches non-bubbling events.\n document.body.addEventListener(eventType, handleDelegatedEvent__, {capture: true});\n }\n}\n\n/**\n * Removes all global delegation listeners registered by `setupActionDelegation`.\n *\n * Useful in test environments where each test needs a clean slate, or in\n * micro-frontend setups where a sub-app is unmounted.\n *\n * After calling this, `setupActionDelegation` can be called again to re-register.\n */\nexport function teardownActionDelegation(): void {\n logger_.logMethod?.('teardownActionDelegation');\n for (const eventType of delegatedEventTypes__) {\n document.body.removeEventListener(eventType, handleDelegatedEvent__, {capture: true});\n }\n delegatedEventTypes__.clear();\n descriptorCache__.clear();\n}\n"
10
9
  ],
11
- "mappings": "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",
12
- "debugId": "4319B6193869E0EC64756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "7E5E853AFB39285764756E2164756E21",
13
12
  "names": []
14
13
  }