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.
@@ -0,0 +1,162 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Chapter 3: The Staged Pipeline — DOM Primitive Bindings</title>
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
10
+ <style>
11
+ body {
12
+ background-color: #f8fafc;
13
+ color: #334155;
14
+ font-family: system-ui, -apple-system, sans-serif;
15
+ line-height: 1.65;
16
+ }
17
+ .story-hero {
18
+ background: linear-gradient(135deg, #065f46 0%, #047857 100%);
19
+ color: #fff;
20
+ padding: 40px 0;
21
+ }
22
+ pre {
23
+ background-color: #0f172a;
24
+ color: #e2e8f0;
25
+ padding: 16px;
26
+ border-radius: 8px;
27
+ font-size: 0.9rem;
28
+ overflow-x: auto;
29
+ }
30
+ code:not(pre code) {
31
+ background-color: #e2e8f0;
32
+ color: #0f172a;
33
+ padding: 2px 6px;
34
+ border-radius: 4px;
35
+ font-size: 0.88em;
36
+ }
37
+ .stage-card {
38
+ border: 1px solid #e2e8f0;
39
+ background: #fff;
40
+ border-radius: 8px;
41
+ padding: 20px;
42
+ }
43
+ </style>
44
+ </head>
45
+
46
+ <body>
47
+
48
+ <header class="story-hero shadow-sm mb-4">
49
+ <div class="container">
50
+ <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
51
+ <div>
52
+ <span class="badge bg-purple text-white mb-2" style="background:#7c3aed;">Chapter 3 of 4</span>
53
+ <h1 class="h3 fw-bold mb-1">The Staged Pipeline Architecture</h1>
54
+ <p class="text-white small mb-0">How src/v3 turns complex delegation into 4 crystal-clear decoupled stages.</p>
55
+ </div>
56
+ <a href="../index.html" class="btn btn-outline-light btn-sm">
57
+ <i class="bi bi-arrow-left me-1"></i> Story Index
58
+ </a>
59
+ </div>
60
+ </div>
61
+ </header>
62
+
63
+ <main class="container pb-5" style="max-width: 900px;">
64
+
65
+ <!-- Overview -->
66
+ <section class="card shadow-sm border-0 p-4 mb-4">
67
+ <h2 class="h5 fw-bold text-dark mb-3">
68
+ <i class="bi bi-diagram-2 text-primary me-2"></i> Inside the <code>src/v3/</code> Pipeline
69
+ </h2>
70
+ <p>
71
+ Rather than writing a monolithic event listener, <code>dom-primitive-bindings</code> breaks the work into 4 decoupled stages where every folder contains an <code>index.js</code> and exports a single function:
72
+ </p>
73
+
74
+ <div class="row g-3">
75
+
76
+ <!-- Stage 1 -->
77
+ <div class="col-md-6">
78
+ <div class="stage-card h-100">
79
+ <span class="badge bg-success mb-2">Stage 1</span>
80
+ <h5 class="h6 fw-bold text-dark mb-1">guards/</h5>
81
+ <p class="small text-muted mb-0">
82
+ Validates and resolves inputs before touching the DOM:
83
+ <br>• <code>container/</code>: Resolves container ID or DOM node.
84
+ <br>• <code>bindings/</code>: Validates that bindings is a valid array of items with <code>event</code> and <code>selector</code>.
85
+ </p>
86
+ </div>
87
+ </div>
88
+
89
+ <!-- Stage 2 -->
90
+ <div class="col-md-6">
91
+ <div class="stage-card h-100">
92
+ <span class="badge bg-info text-dark mb-2">Stage 2</span>
93
+ <h5 class="h6 fw-bold text-dark mb-1">prepare/</h5>
94
+ <p class="small text-muted mb-0">
95
+ Groups all bindings by event type into a <code>Map&lt;eventType, bindings[]&gt;</code>.
96
+ If you have 10 click bindings, it ensures only <strong>one</strong> click listener is attached to the container.
97
+ </p>
98
+ </div>
99
+ </div>
100
+
101
+ <!-- Stage 3 -->
102
+ <div class="col-md-6">
103
+ <div class="stage-card h-100">
104
+ <span class="badge bg-primary mb-2">Stage 3</span>
105
+ <h5 class="h6 fw-bold text-dark mb-1">listeners/</h5>
106
+ <p class="small text-muted mb-0">
107
+ Attaches the container event listeners. Each listener intercepts the native bubbling event and invokes the dispatch pipeline.
108
+ </p>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- Stage 4 -->
113
+ <div class="col-md-6">
114
+ <div class="stage-card h-100">
115
+ <span class="badge bg-warning text-dark mb-2">Stage 4</span>
116
+ <h5 class="h6 fw-bold text-dark mb-1">dispatch/</h5>
117
+ <p class="small text-muted mb-0">
118
+ Matches target elements via <code>event.target.closest(binding.selector)</code>, resolves inputs (keyboard vs click element), and passes <code>{ event, matchElement }</code> to the runner.
119
+ </p>
120
+ </div>
121
+ </div>
122
+
123
+ </div>
124
+ </section>
125
+
126
+ <!-- Code Blueprint -->
127
+ <section class="card shadow-sm border-0 p-4 mb-4">
128
+ <h2 class="h5 fw-bold text-dark mb-3">
129
+ <i class="bi bi-code-square text-success me-2"></i> The Orchestrator (<code>src/v3/index.js</code>)
130
+ </h2>
131
+ <pre class="mb-0"><code>const bindEvents = (containerOrId, bindings = []) => {
132
+ // 1. Validate inputs
133
+ const guarded = runGuards(containerOrId, bindings);
134
+ if (!guarded) return null;
135
+
136
+ // 2. Group bindings by event type
137
+ const { container, bindings: validBindings } = guarded;
138
+ const eventGroups = prepareBindings(validBindings);
139
+
140
+ // 3. Attach container listeners (delegating to dispatch)
141
+ attachListeners(container, eventGroups);
142
+
143
+ return container;
144
+ };</code></pre>
145
+ </section>
146
+
147
+ <!-- Navigation -->
148
+ <div class="d-flex justify-content-between align-items-center mt-4">
149
+ <a href="./02-the-delegation-epiphany.html" class="btn btn-outline-secondary">
150
+ <i class="bi bi-arrow-left me-1"></i> Chapter 2: The Epiphany
151
+ </a>
152
+ <a href="./04-declarative-json-bindings.html" class="btn btn-success">
153
+ Next: Chapter 4 — Declarative JSON Bindings <i class="bi bi-arrow-right ms-1"></i>
154
+ </a>
155
+ </div>
156
+
157
+ </main>
158
+
159
+ </body>
160
+
161
+ </html>
162
+
@@ -0,0 +1,159 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Chapter 4: The Joy of Declarative JSON — DOM Primitive Bindings</title>
8
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
9
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
10
+ <style>
11
+ body {
12
+ background-color: #f8fafc;
13
+ color: #334155;
14
+ font-family: system-ui, -apple-system, sans-serif;
15
+ line-height: 1.65;
16
+ }
17
+ .story-hero {
18
+ background: linear-gradient(135deg, #065f46 0%, #047857 100%);
19
+ color: #fff;
20
+ padding: 40px 0;
21
+ }
22
+ pre {
23
+ background-color: #0f172a;
24
+ color: #e2e8f0;
25
+ padding: 16px;
26
+ border-radius: 8px;
27
+ font-size: 0.9rem;
28
+ overflow-x: auto;
29
+ }
30
+ code:not(pre code) {
31
+ background-color: #e2e8f0;
32
+ color: #0f172a;
33
+ padding: 2px 6px;
34
+ border-radius: 4px;
35
+ font-size: 0.88em;
36
+ }
37
+ .demo-box {
38
+ background: #ffffff;
39
+ border: 1px solid #cbd5e1;
40
+ border-radius: 8px;
41
+ padding: 20px;
42
+ }
43
+ </style>
44
+ </head>
45
+
46
+ <body>
47
+
48
+ <header class="story-hero shadow-sm mb-4">
49
+ <div class="container">
50
+ <div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
51
+ <div>
52
+ <span class="badge bg-success mb-2">Chapter 4 of 4</span>
53
+ <h1 class="h3 fw-bold mb-1">The Joy of Declarative JSON Bindings</h1>
54
+ <p class="text-white small mb-0">Moving from imperative JavaScript arrays to clean, serializable bindings.json specifications.</p>
55
+ </div>
56
+ <a href="../index.html" class="btn btn-outline-light btn-sm">
57
+ <i class="bi bi-arrow-left me-1"></i> Story Index
58
+ </a>
59
+ </div>
60
+ </div>
61
+ </header>
62
+
63
+ <main class="container pb-5" style="max-width: 900px;">
64
+
65
+ <!-- Part 1: Why JSON? -->
66
+ <section class="card shadow-sm border-0 p-4 mb-4">
67
+ <h2 class="h5 fw-bold text-dark mb-3">
68
+ <i class="bi bi-filetype-json text-primary me-2"></i> 1. The Declarative Transformation (v3)
69
+ </h2>
70
+ <p>
71
+ In <strong>v3</strong>, event bindings are completely decoupled from JavaScript code. Instead of writing imperative JS handlers, your events are declared in a clean, serializable <code>bindings.json</code> file:
72
+ </p>
73
+
74
+ <pre><code>// bindings.json
75
+ [
76
+ {
77
+ "event": "click",
78
+ "selector": ".btn-show"
79
+ },
80
+ {
81
+ "event": "keydown",
82
+ "selector": "input[type='search']"
83
+ }
84
+ ]</code></pre>
85
+
86
+ <p class="mb-0">
87
+ Your application simply imports this JSON and feeds it to <code>bindEvents</code>.
88
+ </p>
89
+ </section>
90
+
91
+ <!-- Part 2: Interactive Live Demo -->
92
+ <section class="card shadow-sm border-0 p-4 mb-4">
93
+ <h2 class="h5 fw-bold text-dark mb-2">
94
+ <i class="bi bi-play-circle text-success me-2"></i> 2. Live Interactive Demo
95
+ </h2>
96
+ <p class="small text-muted mb-3">
97
+ This demo is running live in your browser using <code>dom-primitive-bindings (v3)</code>:
98
+ </p>
99
+
100
+ <div class="demo-box mb-3" id="live-demo-container">
101
+ <div class="input-group input-group-sm mb-3" style="max-width: 400px;">
102
+ <input type="search" class="form-control" placeholder="Type here and press Enter...">
103
+ <button class="btn btn-primary" type="button">Search</button>
104
+ </div>
105
+
106
+ <div class="d-flex gap-2">
107
+ <button class="btn btn-outline-primary btn-sm btn-show" data-id="101">Show Row #101</button>
108
+ <button class="btn btn-outline-success btn-sm btn-show" data-id="102">Show Row #102</button>
109
+ <button class="btn btn-outline-secondary btn-sm btn-show" data-id="103">Show Row #103</button>
110
+ </div>
111
+ </div>
112
+
113
+ <div class="bg-dark text-info p-3 rounded font-monospace small" id="live-log">
114
+ // Click any button or press Enter in the search input to observe the event captured from bindings.json...
115
+ </div>
116
+ </section>
117
+
118
+ <!-- Navigation -->
119
+ <div class="d-flex justify-content-between align-items-center mt-4">
120
+ <a href="./03-the-staged-pipeline.html" class="btn btn-outline-secondary">
121
+ <i class="bi bi-arrow-left me-1"></i> Chapter 3: The Pipeline
122
+ </a>
123
+ <a href="../index.html" class="btn btn-success">
124
+ <i class="bi bi-house me-1"></i> Return to Documentation Hub
125
+ </a>
126
+ </div>
127
+
128
+ </main>
129
+
130
+ <script type="module" src="../../dist/v3/min.js"></script>
131
+ <script type="module">
132
+ const logBox = document.getElementById("live-log");
133
+
134
+ const jsonBindings = [
135
+ { event: "click", selector: ".btn-show" },
136
+ { event: "keydown", selector: "input[type='search']" }
137
+ ];
138
+
139
+ const activeBindings = jsonBindings.map((binding) => ({
140
+ ...binding,
141
+ onExtract: (result, event, matchElement) => {
142
+ const payload = {
143
+ event: event.type,
144
+ selector: binding.selector,
145
+ targetTag: matchElement.tagName,
146
+ key: event.key,
147
+ id: matchElement.dataset.id
148
+ };
149
+ logBox.innerHTML = `Event Dispatched: <span class="text-warning">${JSON.stringify(payload)}</span>`;
150
+ }
151
+ }));
152
+
153
+ window.ks.domPrimitiveBindings?.bindEvents("live-demo-container", activeBindings);
154
+ </script>
155
+
156
+ </body>
157
+
158
+ </html>
159
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dom-primitive-bindings",
3
- "version": "1.0.0",
3
+ "version": "1.3.1",
4
4
  "description": "Declarative, instruction-driven DOM delegated event bindings",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "files": [
21
21
  "src/index.js",
22
- "src/v1",
22
+ "src/v3",
23
23
  "docs",
24
24
  "README.md",
25
25
  "LICENSE"
@@ -33,4 +33,4 @@
33
33
  "devDependencies": {
34
34
  "vite": "^6.4.1"
35
35
  }
36
- }
36
+ }
package/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from "./v1/index.js";
2
- export { default } from "./v1/index.js";
1
+ export * from "./v3/index.js";
2
+ export { default } from "./v3/index.js";
3
3
 
@@ -10,8 +10,9 @@ const registerGlobal = (bindEvents, metadata = meta) => {
10
10
  bindEvents
11
11
  };
12
12
 
13
+ globalThis.ks.bindEvents ??= bindEvents;
14
+
13
15
  return globalThis.ks.domPrimitiveBindings;
14
16
  };
15
17
 
16
18
  export default registerGlobal;
17
-
@@ -1,7 +1,6 @@
1
1
  export const meta = {
2
2
  name: "dom-primitive-bindings",
3
- version: "1.0.0"
3
+ version: "3.0.0"
4
4
  };
5
5
 
6
6
  export default meta;
7
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes