dom-primitive-bindings 1.0.0 → 1.3.1

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
@@ -1,61 +1,91 @@
1
1
  # DOM Primitive Bindings
2
2
 
3
- > Modern, lightweight, delegated event engine for browser DOMs. Attach exactly one listener per event type to any container; let bubbling handle matching, runners, and extraction with zero re-binding overhead.
3
+ > Modern, lightweight, single-listener delegated event engine for browser DOMs. Driven by declarative `bindings.json` configurations with zero DOM manipulation and zero schema extraction.
4
4
 
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
- [![Tests](https://img.shields.io/badge/tests-passing-brightgreen.svg)]()
7
- [![Single Source of Truth](https://img.shields.io/badge/Version-v1-blue.svg)]()
5
+ [![npm version](https://img.shields.io/npm/v/dom-primitive-bindings.svg?style=flat-square)](https://www.npmjs.com/package/dom-primitive-bindings)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
7
+ [![Single Source of Truth](https://img.shields.io/badge/Version-v3-blue.svg?style=flat-square)]()
8
+ [![Documentation](https://img.shields.io/badge/Docs-Architecture%20%26%20Stories-green.svg?style=flat-square)](./docs/index.html)
8
9
 
9
10
  ---
10
11
 
11
- ## 🎯 The Core Concept
12
+ ## 📖 The 4-Part Event Delegation Story
12
13
 
13
- Traditional client-side code attaches listeners to every button, link, and input. When tables are refreshed, cards are added, or modals render dynamic markup, those listeners break or leak memory unless manually re-attached.
14
+ Explore the interactive interactive story chapters in [`docs/stories/`](./docs/index.html):
14
15
 
15
- **DOM Primitive Bindings** inverts the architecture:
16
- - Attach **one listener** per event type to the parent container (`table`, `form`, `card-grid`).
17
- - As events bubble up, `closest(selector)` identifies target elements.
18
- - The associated `runner` executes and forwards data cleanly to `onExtract`.
19
- - Dynamically created DOM elements are supported immediately with **zero re-binding**.
16
+ 1. **[Chapter 1: The Everyday Habit & The Listener Trap](./docs/stories/01-the-listener-trap.html)**
17
+ Why attaching listeners to individual elements causes memory leaks, double-trigger cascades, and dead-zones on dynamic elements.
18
+ 2. **[Chapter 2: The Delegation Epiphany](./docs/stories/02-the-delegation-epiphany.html)**
19
+ Harnessing browser event bubbling: 1 container listener catching bubbling events forever.
20
+ 3. **[Chapter 3: The Staged Pipeline Architecture](./docs/stories/03-the-staged-pipeline.html)**
21
+ Inside the decoupled 4-stage pipeline: `guards` $\to$ `prepare` $\to$ `listeners` $\to$ `dispatch`.
22
+ 4. **[Chapter 4: The Joy of Declarative JSON](./docs/stories/04-declarative-json-bindings.html)**
23
+ Moving from imperative JavaScript arrays to clean, serializable `bindings.json` specifications with a live interactive demo.
20
24
 
21
25
  ---
22
26
 
23
- ## 🏗️ Staged Architecture (`src/v1/`)
27
+ ## 🎯 The Philosophy: The Wiring Layer
24
28
 
25
- The repository strictly enforces a staged pipeline where every directory contains an `index.js` and all files export a single function as `default`:
29
+ A common mistake in UI architecture is conflating **event wiring** with **DOM manipulation** or **data extraction**:
30
+
31
+ - **`dom-primitive-bindings` (This Repository):**
32
+ Pure **Wiring Layer**. Attaches one container listener per event type, matches bubbling targets via `closest(selector)`, and delivers `{ event, targetElement }`. It does **not** manipulate DOM elements and does **not** extract table schemas into objects.
33
+ - **`dom-primitive-engine` (Sibling Repository):**
34
+ Pure **Extraction Layer**. Receives the matched target element and executes declarative instruction pipelines (e.g. `closest("tr")`, `querySelectorAll("td")`, column mapping) to produce clean JSON.
35
+
36
+ ```text
37
+ [ User Action in Browser ]
38
+ │
39
+ ▼
40
+ ┌───────────────────────────────┐
41
+ │ dom-primitive-bindings │ ◄── Wiring Layer: Catches event & matches target
42
+ │ (guards → prepare → dispatch)│
43
+ └──────────────┬────────────────┘
44
+ │ delivers { event, targetElement }
45
+ ▼
46
+ ┌───────────────────────────────┐
47
+ │ Consumer / App Logic │ ◄── Extraction (dom-primitive-engine) or App Handler
48
+ └───────────────────────────────┘
49
+ ```
50
+
51
+ ---
52
+
53
+ ## 🏗️ Staged Architecture (`src/v3/`)
54
+
55
+ The engine enforces a staged pipeline where every directory contains an `index.js` and all files export a single function as `default`:
26
56
 
27
57
  ```text
28
- src/
29
- └── v1/
30
- ├── guards/ # Validates container and bindings array
31
- │ ├── container/ # Validates and resolves 1st input (container / ID)
32
- │ ├── bindings/ # Validates 2nd input (bindings array)
33
- │ └── index.js
34
- ├── prepare/ # Groups bindings by event type into Map
35
- │ ├── groupBindings.js
36
- │ └── index.js
37
- ├── listeners/ # Attaches single listener per event type to container
38
- │ ├── attachListener.js
39
- │ └── index.js
40
- ├── dispatch/ # Handles event bubbling, runner execution & extraction
41
- │ ├── getStartInput.js
42
- │ ├── getClientData.js
43
- │ ├── executeBinding.js
44
- │ └── index.js
45
- ├── register/ # Exposes module onto window.ks.domPrimitiveBindings
46
- │ ├── meta.js
47
- │ └── index.js
48
- └── index.js # Orchestrator exporting bindEvents
58
+ src/v3/
59
+ ├── guards/ # Validates container & bindings array
60
+ │ ├── container/ # Resolves 1st input (container ID or DOM element)
61
+ │ ├── bindings/ # Filters and validates 2nd input (bindings array)
62
+ │ └── index.js
63
+ ├── prepare/ # Groups bindings by event type into Map
64
+ │ ├── groupBindings.js
65
+ │ └── index.js
66
+ ├── listeners/ # Attaches single container listener per event type
67
+ │ ├── attachListener.js
68
+ │ └── index.js
69
+ ├── dispatch/ # Handles event bubbling, target matching & execution
70
+ │ ├── getStartInput.js
71
+ │ ├── getClientData.js
72
+ │ ├── executeBinding.js
73
+ │ └── index.js
74
+ ├── register/ # Exposes module onto window.ks.domPrimitiveBindings
75
+ │ ├── meta.js
76
+ │ └── index.js
77
+ └── index.js # Orchestrator
49
78
  ```
50
79
 
51
80
  ### Key Design Disciplines
52
81
  1. **Zero Comments:** The folder hierarchy and descriptive file names convey the full narrative without inline code comments.
53
82
  2. **Folder Discipline:** Every folder contains an `index.js` public gateway.
54
83
  3. **Single Function Default Export:** No default export objects; every file exports a single function.
84
+ 4. **Declarative JSON:** Bindings are defined in serializable `bindings.json` files.
55
85
 
56
86
  ---
57
87
 
58
- ## 🚀 Interactive Browser Samples (`samples/v1/`)
88
+ ## 🚀 Interactive Browser Samples (`samples/v3/`)
59
89
 
60
90
  Start the Vite development server to view and interact with real browser DOM events:
61
91
 
@@ -65,47 +95,55 @@ npm run dev
65
95
  ```
66
96
 
67
97
  Open in Chrome or Edge:
68
- - **`samples/v1/tableWithSearch/`** — Delegated table row clicks and live Enter-key search input.
69
- - **`samples/v1/cardGrid/`** — Dynamic card insertion into DOM with instant delegated action buttons.
70
- - **`samples/v1/formEvents/`** — Live form field inputs, dropdown selection changes, and submit/clear buttons.
98
+ - **`samples/v3/tableWithSearch/`** — Declarative table row clicks and live Enter-key search input loaded from `bindings.json`.
99
+ - **`samples/v3/cardGrid/`** — Declarative card button and card body click bindings loaded from `bindings.json`.
100
+ - **`samples/v3/formEvents/`** — Declarative input, change, and button click bindings loaded from `bindings.json`.
71
101
 
72
102
  ---
73
103
 
74
104
  ## 📦 Usage
75
105
 
76
- ### Browser (ES Module / Script)
106
+ ### 1. Declare `bindings.json`
77
107
 
78
- ```html
79
- <script type="module" src="./docs/dist/v1/min.js"></script>
80
- <script type="module">
81
- const bindings = [
82
- {
83
- event: "click",
84
- selector: ".btn-cart",
85
- runner: (target) => ({ productId: target.dataset.id }),
86
- onExtract: (data) => console.log("Added to cart:", data)
87
- }
88
- ];
89
-
90
- window.ks.domPrimitiveBindings.bindEvents("products-container", bindings);
91
- </script>
108
+ ```json
109
+ [
110
+ {
111
+ "event": "click",
112
+ "selector": ".btn-action"
113
+ },
114
+ {
115
+ "event": "keydown",
116
+ "selector": "input[type='search']"
117
+ }
118
+ ]
92
119
  ```
93
120
 
94
- ### Module Import
121
+ ### 2. Run with `bindEvents`
95
122
 
96
123
  ```javascript
124
+ import bindings from "./bindings.json" with { type: "json" };
97
125
  import { bindEvents } from "dom-primitive-bindings";
98
126
 
99
- bindEvents(containerElement, [
100
- {
101
- event: "click",
102
- selector: ".action-btn",
103
- runner: (btn) => btn.dataset.action,
104
- onExtract: (action) => console.log("Action:", action)
105
- }
106
- ]);
127
+ bindEvents("container-id", bindings);
107
128
  ```
108
129
 
130
+ Or via global browser script:
131
+
132
+ ```html
133
+ <script type="module" src="./docs/dist/v3/min.js"></script>
134
+ <script type="module">
135
+ import bindings from "./bindings.json" with { type: "json" };
136
+ window.ks.domPrimitiveBindings.bindEvents("container-id", bindings);
137
+ </script>
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 📚 Technical Specifications
143
+
144
+ - **[Architecture & Design Story](./docs/architecture.md)**: Deep dive into the 4 internal stages and data flow.
145
+ - **[Binding Specification Schema](./docs/binding-spec.md)**: Complete property reference for `bindings.json`.
146
+
109
147
  ---
110
148
 
111
149
  ## 🧪 Testing & Build
@@ -114,7 +152,7 @@ bindEvents(containerElement, [
114
152
  # Run unit tests
115
153
  npm test
116
154
 
117
- # Build production bundle to docs/dist/v1/min.js
155
+ # Build production bundle to docs/dist/v3/min.js
118
156
  npm run build
119
157
  ```
120
158
 
@@ -123,4 +161,3 @@ npm run build
123
161
  ## 📄 License
124
162
 
125
163
  MIT © KeshavSoft
126
-
@@ -0,0 +1,111 @@
1
+ # Architecture & Design Story — DOM Primitive Bindings
2
+
3
+ This document details the architectural philosophy, data flow, and design trade-offs behind **DOM Primitive Bindings**.
4
+
5
+ ---
6
+
7
+ ## 1. The Core Architectural Philosophy
8
+
9
+ ### Separation of Concerns: The Wiring Layer vs. The Extraction Layer
10
+
11
+ Modern frontend architectures fail when they blur the boundary between **how events are wired** and **how data is extracted or mutated**:
12
+
13
+ ```text
14
+ ┌─────────────────────────────────┐
15
+ │ Browser DOM │ <-- Stateful View (Table, Form, Cards)
16
+ └────────────────┬────────────────┘
17
+ │ user interaction (click, input, keydown)
18
+ ▼
19
+ ┌─────────────────────────────────┐
20
+ │ dom-primitive-bindings │ <-- Responsibility: The Wiring Layer
21
+ │ (guards → prepare → dispatch) │ • Single listener on container
22
+ └────────────────┬────────────────┘ • Matches closest(selector)
23
+ │ passes { event, targetElement }
24
+ ▼
25
+ ┌─────────────────────────────────┐
26
+ │ dom-primitive-engine │ <-- Responsibility: The Extraction Layer
27
+ │ (declarative instructions) │ • Traverses DOM (tr, td)
28
+ └────────────────┬────────────────┘ • Produces clean JSON object
29
+ │ outputs clean Plain Data
30
+ ▼
31
+ ┌─────────────────────────────────┐
32
+ │ Business Logic / API Call │ <-- Consumes Plain Data
33
+ └─────────────────────────────────┘
34
+ ```
35
+
36
+ By strictly separating event wiring into `dom-primitive-bindings`:
37
+ 1. **Zero DOM manipulation**: Bindings never alter, insert, or delete DOM elements.
38
+ 2. **Zero schema extraction**: Bindings never parse table cells or form schemas into business models.
39
+ 3. **Pure delegation**: Exactly **one listener per event type** is attached to the parent container. Bubbling handles target matching.
40
+
41
+ ---
42
+
43
+ ## 2. Why Delegated Bindings over Element Listeners?
44
+
45
+ | Approach | Memory Usage | Dynamic Element Support | Duplicate Fire Risk |
46
+ | :--- | :--- | :--- | :--- |
47
+ | **Direct Listeners** (`element.addEventListener`) | High ($O(N)$ listeners) | Fails on newly added DOM elements | High (re-attaching duplicates listeners) |
48
+ | **DOM Primitive Bindings** (Container Delegation) | Minimal ($O(1)$ listener per event type) | Works instantly on dynamic elements | Zero (single stable container listener) |
49
+
50
+ ---
51
+
52
+ ## 3. The 4-Stage Internal Pipeline (`src/v3/`)
53
+
54
+ The engine operates on a strictly staged, functional pipeline where every folder contains an `index.js` and exports a single function as `default`:
55
+
56
+ ```text
57
+ src/v3/
58
+ ├── guards/ # Validates container & bindings array
59
+ │ ├── container/ # Resolves 1st input (container ID or DOM element)
60
+ │ ├── bindings/ # Filters and validates 2nd input (bindings array)
61
+ │ └── index.js
62
+ ├── prepare/ # Groups bindings by event type into Map
63
+ │ ├── groupBindings.js
64
+ │ └── index.js
65
+ ├── listeners/ # Attaches single container listener per event type
66
+ │ ├── attachListener.js
67
+ │ └── index.js
68
+ ├── dispatch/ # Handles event bubbling, target matching & execution
69
+ │ ├── getStartInput.js
70
+ │ ├── getClientData.js
71
+ │ ├── executeBinding.js
72
+ │ └── index.js
73
+ ├── register/ # Exposes module onto window.ks.domPrimitiveBindings
74
+ │ ├── meta.js
75
+ │ └── index.js
76
+ └── index.js # Orchestrator
77
+ ```
78
+
79
+ ### Stage Details
80
+
81
+ 1. **`guards/`**: Validates inputs before any DOM mutation occurs.
82
+ - `container/`: Resolves string IDs via `document.getElementById` or verifies existing element.
83
+ - `bindings/`: Filters invalid items and ensures at least one valid binding exists.
84
+ 2. **`prepare/`**: Groups bindings into a `Map<eventType, bindings[]>`.
85
+ - If 10 separate selectors listen for `click`, they are aggregated under the single `"click"` event group.
86
+ 3. **`listeners/`**: Attaches exactly one native event listener to the container per event type.
87
+ 4. **`dispatch/`**:
88
+ - Intercepts the bubbling event.
89
+ - Resolves matching element via `event.target.closest(binding.selector)`.
90
+ - Resolves starting input (`event` for keyboard events, `matchElement` for clicks).
91
+ - Invokes runner and forwards data to `onExtract`.
92
+
93
+ ---
94
+
95
+ ## 4. Responsibility Boundaries
96
+
97
+ | Actor | What It Does | What It NEVER Does |
98
+ | :--- | :--- | :--- |
99
+ | **Container Element** | Acts as the stable anchor for bubbling events | Does not know about inner button schemas |
100
+ | **`bindings.json`** | Declares `event` and `selector` | Does not execute imperative logic |
101
+ | **`dom-primitive-bindings`** | Resolves target, manages delegation pipeline | Does not extract table rows or mutate markup |
102
+ | **`dom-primitive-engine`** | Extracts clean JSON data from the matched target | Does not manage event listeners |
103
+
104
+ ---
105
+
106
+ ## 5. Version Evolution (`v3` as Single Source of Truth)
107
+
108
+ - **v1**: Staged architecture established with zero code comments and single-function default exports.
109
+ - **v2**: Removed accidental DOM manipulation and cell extraction from samples, solidifying the pure delegation boundary.
110
+ - **v3**: Declarative JSON transformation. Replaced imperative `.js` event arrays with pure, serializable `bindings.json` configurations.
111
+
@@ -0,0 +1,86 @@
1
+ # Binding Specification — DOM Primitive Bindings
2
+
3
+ This document defines the normative schema and runtime behavior for declarative `bindings.json` files.
4
+
5
+ ---
6
+
7
+ ## 1. Schema Overview
8
+
9
+ A bindings file is an array of binding specification objects:
10
+
11
+ ```json
12
+ [
13
+ {
14
+ "event": "click",
15
+ "selector": ".ks-btn-show",
16
+ "root": "element",
17
+ "clientData": {
18
+ "context": "tableRow"
19
+ }
20
+ }
21
+ ]
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 2. Property Definitions
27
+
28
+ ### `event` (Required)
29
+ - **Type**: `string`
30
+ - **Description**: The standard browser DOM event name to listen for on the container (e.g. `"click"`, `"keydown"`, `"input"`, `"change"`, `"submit"`).
31
+ - **Behavior**: The engine groups all bindings with the same `event` name under a single native event listener on the container element.
32
+
33
+ ### `selector` (Required)
34
+ - **Type**: `string`
35
+ - **Description**: Standard CSS selector used by `event.target.closest(selector)` to identify whether the bubbling event originated from or within a target element.
36
+ - **Examples**:
37
+ - `".ks-btn-show"`
38
+ - `"input[type='search'], input"`
39
+ - `".btn-action"`
40
+ - `".product-card"`
41
+
42
+ ### `root` (Optional)
43
+ - **Type**: `string` (`"element"` | `"event"`)
44
+ - **Default**: `"element"` (automatically defaults to `"event"` for key events such as `keydown`, `keyup`, `keypress`).
45
+ - **Description**: Determines what is passed as the first argument to the runner function:
46
+ - `"element"`: passes the matched DOM element (`matchElement`).
47
+ - `"event"`: passes the native browser `Event` object.
48
+
49
+ ### `clientData` (Optional)
50
+ - **Type**: `object`
51
+ - **Description**: Arbitrary user-defined context passed along into the dispatch pipeline. The engine merges this into the client context object alongside `event` and `targetElement`.
52
+
53
+ ### `instructions` (Optional)
54
+ - **Type**: `array`
55
+ - **Description**: Declarative extraction instructions intended for handoff to `dom-primitive-engine`.
56
+
57
+ ---
58
+
59
+ ## 3. Runtime Dispatch Lifecycle
60
+
61
+ When an event fires inside the container:
62
+
63
+ ```text
64
+ Browser Event Fires
65
+ │
66
+ ▼
67
+ Container Listener Intercepts (listeners/attachListener.js)
68
+ │
69
+ ▼
70
+ Find Matching Element: event.target.closest(binding.selector)
71
+ │
72
+ ├── No match / not inside container ──> Discard (continue)
73
+ │
74
+ ▼
75
+ Resolve Start Input (dispatch/getStartInput.js)
76
+ │
77
+ ├── Key event or root === "event" ──> Pass event
78
+ └── Otherwise ──> Pass matchElement
79
+ │
80
+ ▼
81
+ Execute Runner (dispatch/executeBinding.js)
82
+ │
83
+ ▼
84
+ Forward to onExtract(result, event, matchElement)
85
+ ```
86
+
package/docs/dist/min.js CHANGED
@@ -1,12 +1,13 @@
1
1
  const u = {
2
2
  name: "dom-primitive-bindings",
3
- version: "1.0.0"
3
+ version: "3.0.0"
4
4
  }, c = (t, n = u) => {
5
+ var e;
5
6
  if (!(!t || typeof globalThis > "u"))
6
7
  return globalThis.ks ?? (globalThis.ks = {}), globalThis.ks.domPrimitiveBindings = {
7
8
  meta: n,
8
9
  bindEvents: t
9
- }, globalThis.ks.domPrimitiveBindings;
10
+ }, (e = globalThis.ks).bindEvents ?? (e.bindEvents = t), globalThis.ks.domPrimitiveBindings;
10
11
  }, l = (t) => typeof t == "string" ? document.getElementById(t) || document.querySelector(t) : t && typeof t == "object" && "addEventListener" in t ? t : null, a = (t) => {
11
12
  if (!t) return null;
12
13
  const n = l(t);
@@ -42,19 +43,19 @@ const u = {
42
43
  const s = (i = (r = n.target) == null ? void 0 : r.closest) == null ? void 0 : i.call(r, o.selector);
43
44
  !s || !e.contains(s) || v({ binding: o, event: n, matchElement: s });
44
45
  }
45
- }, E = (t, n, e) => {
46
+ }, k = (t, n, e) => {
46
47
  t.addEventListener(n, (r) => {
47
48
  B({ bindings: e, event: r, container: t });
48
49
  });
49
- }, k = (t, n) => {
50
+ }, E = (t, n) => {
50
51
  for (const [e, r] of n.entries())
51
- E(t, e, r);
52
+ k(t, e, r);
52
53
  return t;
53
54
  }, T = (t, n = []) => {
54
55
  const e = p(t, n);
55
56
  if (!e) return null;
56
57
  const { container: r, bindings: i } = e, o = y(i);
57
- return k(r, o), r;
58
+ return E(r, o), r;
58
59
  };
59
60
  c(T);
60
61
  export {
@@ -0,0 +1,64 @@
1
+ const u = {
2
+ name: "dom-primitive-bindings",
3
+ version: "2.0.0"
4
+ }, c = (t, n = u) => {
5
+ var e;
6
+ if (!(!t || typeof globalThis > "u"))
7
+ return globalThis.ks ?? (globalThis.ks = {}), globalThis.ks.domPrimitiveBindings = {
8
+ meta: n,
9
+ bindEvents: t
10
+ }, (e = globalThis.ks).bindEvents ?? (e.bindEvents = t), globalThis.ks.domPrimitiveBindings;
11
+ }, l = (t) => typeof t == "string" ? document.getElementById(t) || document.querySelector(t) : t && typeof t == "object" && "addEventListener" in t ? t : null, a = (t) => {
12
+ if (!t) return null;
13
+ const n = l(t);
14
+ return n || null;
15
+ }, f = (t) => Array.isArray(t) ? t.filter((n) => n && typeof n == "object" && typeof n.event == "string" && typeof n.selector == "string") : [], g = (t) => {
16
+ const n = f(t);
17
+ return n.length === 0 ? null : n;
18
+ }, p = (t, n) => {
19
+ const e = a(t);
20
+ if (!e) return null;
21
+ const r = g(n);
22
+ return r ? { container: e, bindings: r } : null;
23
+ }, d = (t) => {
24
+ const n = /* @__PURE__ */ new Map();
25
+ for (const e of t) {
26
+ const r = n.get(e.event) ?? [];
27
+ r.push(e), n.set(e.event, r);
28
+ }
29
+ return n;
30
+ }, y = (t) => d(t), m = (t, n, e) => {
31
+ var r;
32
+ return t.root === "event" || (r = n == null ? void 0 : n.type) != null && r.startsWith("key") ? n : e;
33
+ }, h = (t, n, e) => ({
34
+ ...t.clientData,
35
+ event: n,
36
+ targetElement: e
37
+ }), v = ({ binding: t, event: n, matchElement: e }) => {
38
+ const r = m(t, n, e), i = h(t, n, e), o = t.runner, s = typeof o == "function" ? o(r, t.instructions, i) : r;
39
+ return s != null && typeof t.onExtract == "function" && t.onExtract(s, n, e), s;
40
+ }, B = ({ bindings: t, event: n, container: e }) => {
41
+ var r, i;
42
+ for (const o of t) {
43
+ const s = (i = (r = n.target) == null ? void 0 : r.closest) == null ? void 0 : i.call(r, o.selector);
44
+ !s || !e.contains(s) || v({ binding: o, event: n, matchElement: s });
45
+ }
46
+ }, k = (t, n, e) => {
47
+ t.addEventListener(n, (r) => {
48
+ B({ bindings: e, event: r, container: t });
49
+ });
50
+ }, E = (t, n) => {
51
+ for (const [e, r] of n.entries())
52
+ k(t, e, r);
53
+ return t;
54
+ }, T = (t, n = []) => {
55
+ const e = p(t, n);
56
+ if (!e) return null;
57
+ const { container: r, bindings: i } = e, o = y(i);
58
+ return E(r, o), r;
59
+ };
60
+ c(T);
61
+ export {
62
+ T as bindEvents,
63
+ T as default
64
+ };
@@ -0,0 +1,64 @@
1
+ const u = {
2
+ name: "dom-primitive-bindings",
3
+ version: "3.0.0"
4
+ }, c = (t, n = u) => {
5
+ var e;
6
+ if (!(!t || typeof globalThis > "u"))
7
+ return globalThis.ks ?? (globalThis.ks = {}), globalThis.ks.domPrimitiveBindings = {
8
+ meta: n,
9
+ bindEvents: t
10
+ }, (e = globalThis.ks).bindEvents ?? (e.bindEvents = t), globalThis.ks.domPrimitiveBindings;
11
+ }, l = (t) => typeof t == "string" ? document.getElementById(t) || document.querySelector(t) : t && typeof t == "object" && "addEventListener" in t ? t : null, a = (t) => {
12
+ if (!t) return null;
13
+ const n = l(t);
14
+ return n || null;
15
+ }, f = (t) => Array.isArray(t) ? t.filter((n) => n && typeof n == "object" && typeof n.event == "string" && typeof n.selector == "string") : [], g = (t) => {
16
+ const n = f(t);
17
+ return n.length === 0 ? null : n;
18
+ }, p = (t, n) => {
19
+ const e = a(t);
20
+ if (!e) return null;
21
+ const r = g(n);
22
+ return r ? { container: e, bindings: r } : null;
23
+ }, d = (t) => {
24
+ const n = /* @__PURE__ */ new Map();
25
+ for (const e of t) {
26
+ const r = n.get(e.event) ?? [];
27
+ r.push(e), n.set(e.event, r);
28
+ }
29
+ return n;
30
+ }, y = (t) => d(t), m = (t, n, e) => {
31
+ var r;
32
+ return t.root === "event" || (r = n == null ? void 0 : n.type) != null && r.startsWith("key") ? n : e;
33
+ }, h = (t, n, e) => ({
34
+ ...t.clientData,
35
+ event: n,
36
+ targetElement: e
37
+ }), v = ({ binding: t, event: n, matchElement: e }) => {
38
+ const r = m(t, n, e), i = h(t, n, e), o = t.runner, s = typeof o == "function" ? o(r, t.instructions, i) : r;
39
+ return s != null && typeof t.onExtract == "function" && t.onExtract(s, n, e), s;
40
+ }, B = ({ bindings: t, event: n, container: e }) => {
41
+ var r, i;
42
+ for (const o of t) {
43
+ const s = (i = (r = n.target) == null ? void 0 : r.closest) == null ? void 0 : i.call(r, o.selector);
44
+ !s || !e.contains(s) || v({ binding: o, event: n, matchElement: s });
45
+ }
46
+ }, k = (t, n, e) => {
47
+ t.addEventListener(n, (r) => {
48
+ B({ bindings: e, event: r, container: t });
49
+ });
50
+ }, E = (t, n) => {
51
+ for (const [e, r] of n.entries())
52
+ k(t, e, r);
53
+ return t;
54
+ }, T = (t, n = []) => {
55
+ const e = p(t, n);
56
+ if (!e) return null;
57
+ const { container: r, bindings: i } = e, o = y(i);
58
+ return E(r, o), r;
59
+ };
60
+ c(T);
61
+ export {
62
+ T as bindEvents,
63
+ T as default
64
+ };