@livetemplate/client 0.1.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.
Files changed (100) hide show
  1. package/README.md +179 -0
  2. package/dist/constants.d.ts +2 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +19 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/dom/directives.d.ts +13 -0
  7. package/dist/dom/directives.d.ts.map +1 -0
  8. package/dist/dom/directives.js +137 -0
  9. package/dist/dom/directives.js.map +1 -0
  10. package/dist/dom/event-delegation.d.ts +24 -0
  11. package/dist/dom/event-delegation.d.ts.map +1 -0
  12. package/dist/dom/event-delegation.js +437 -0
  13. package/dist/dom/event-delegation.js.map +1 -0
  14. package/dist/dom/focus-manager.d.ts +19 -0
  15. package/dist/dom/focus-manager.d.ts.map +1 -0
  16. package/dist/dom/focus-manager.js +144 -0
  17. package/dist/dom/focus-manager.js.map +1 -0
  18. package/dist/dom/form-disabler.d.ts +8 -0
  19. package/dist/dom/form-disabler.d.ts.map +1 -0
  20. package/dist/dom/form-disabler.js +32 -0
  21. package/dist/dom/form-disabler.js.map +1 -0
  22. package/dist/dom/loading-indicator.d.ts +9 -0
  23. package/dist/dom/loading-indicator.d.ts.map +1 -0
  24. package/dist/dom/loading-indicator.js +50 -0
  25. package/dist/dom/loading-indicator.js.map +1 -0
  26. package/dist/dom/modal-manager.d.ts +11 -0
  27. package/dist/dom/modal-manager.d.ts.map +1 -0
  28. package/dist/dom/modal-manager.js +62 -0
  29. package/dist/dom/modal-manager.js.map +1 -0
  30. package/dist/dom/observer-manager.d.ts +19 -0
  31. package/dist/dom/observer-manager.d.ts.map +1 -0
  32. package/dist/dom/observer-manager.js +64 -0
  33. package/dist/dom/observer-manager.js.map +1 -0
  34. package/dist/livetemplate-client.browser.js +44 -0
  35. package/dist/livetemplate-client.browser.js.map +7 -0
  36. package/dist/livetemplate-client.d.ts +106 -0
  37. package/dist/livetemplate-client.d.ts.map +1 -0
  38. package/dist/livetemplate-client.js +507 -0
  39. package/dist/livetemplate-client.js.map +1 -0
  40. package/dist/state/form-lifecycle-manager.d.ts +19 -0
  41. package/dist/state/form-lifecycle-manager.d.ts.map +1 -0
  42. package/dist/state/form-lifecycle-manager.js +64 -0
  43. package/dist/state/form-lifecycle-manager.js.map +1 -0
  44. package/dist/state/tree-renderer.d.ts +27 -0
  45. package/dist/state/tree-renderer.d.ts.map +1 -0
  46. package/dist/state/tree-renderer.js +359 -0
  47. package/dist/state/tree-renderer.js.map +1 -0
  48. package/dist/tests/event-delegation.test.d.ts +2 -0
  49. package/dist/tests/event-delegation.test.d.ts.map +1 -0
  50. package/dist/tests/event-delegation.test.js +102 -0
  51. package/dist/tests/event-delegation.test.js.map +1 -0
  52. package/dist/tests/focus-manager.test.d.ts +2 -0
  53. package/dist/tests/focus-manager.test.d.ts.map +1 -0
  54. package/dist/tests/focus-manager.test.js +45 -0
  55. package/dist/tests/focus-manager.test.js.map +1 -0
  56. package/dist/tests/form-disabler.test.d.ts +2 -0
  57. package/dist/tests/form-disabler.test.d.ts.map +1 -0
  58. package/dist/tests/form-disabler.test.js +35 -0
  59. package/dist/tests/form-disabler.test.js.map +1 -0
  60. package/dist/tests/form-lifecycle-manager.test.d.ts +2 -0
  61. package/dist/tests/form-lifecycle-manager.test.d.ts.map +1 -0
  62. package/dist/tests/form-lifecycle-manager.test.js +90 -0
  63. package/dist/tests/form-lifecycle-manager.test.js.map +1 -0
  64. package/dist/tests/modal-manager.test.d.ts +2 -0
  65. package/dist/tests/modal-manager.test.d.ts.map +1 -0
  66. package/dist/tests/modal-manager.test.js +80 -0
  67. package/dist/tests/modal-manager.test.js.map +1 -0
  68. package/dist/tests/rate-limit.test.d.ts +2 -0
  69. package/dist/tests/rate-limit.test.d.ts.map +1 -0
  70. package/dist/tests/rate-limit.test.js +38 -0
  71. package/dist/tests/rate-limit.test.js.map +1 -0
  72. package/dist/tests/test-conditional-debug.test.d.ts +8 -0
  73. package/dist/tests/test-conditional-debug.test.d.ts.map +1 -0
  74. package/dist/tests/test-conditional-debug.test.js +187 -0
  75. package/dist/tests/test-conditional-debug.test.js.map +1 -0
  76. package/dist/tests/test-reconstruction.test.d.ts +8 -0
  77. package/dist/tests/test-reconstruction.test.d.ts.map +1 -0
  78. package/dist/tests/test-reconstruction.test.js +284 -0
  79. package/dist/tests/test-reconstruction.test.js.map +1 -0
  80. package/dist/transport/websocket.d.ts +62 -0
  81. package/dist/transport/websocket.d.ts.map +1 -0
  82. package/dist/transport/websocket.js +194 -0
  83. package/dist/transport/websocket.js.map +1 -0
  84. package/dist/types.d.ts +34 -0
  85. package/dist/types.d.ts.map +1 -0
  86. package/dist/types.js +3 -0
  87. package/dist/types.js.map +1 -0
  88. package/dist/utils/logger.d.ts +32 -0
  89. package/dist/utils/logger.d.ts.map +1 -0
  90. package/dist/utils/logger.js +77 -0
  91. package/dist/utils/logger.js.map +1 -0
  92. package/dist/utils/rate-limit.d.ts +10 -0
  93. package/dist/utils/rate-limit.d.ts.map +1 -0
  94. package/dist/utils/rate-limit.js +37 -0
  95. package/dist/utils/rate-limit.js.map +1 -0
  96. package/dist/utils/testing.d.ts +14 -0
  97. package/dist/utils/testing.d.ts.map +1 -0
  98. package/dist/utils/testing.js +51 -0
  99. package/dist/utils/testing.js.map +1 -0
  100. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # LiveTemplate TypeScript Client
2
+
3
+ A TypeScript client for consuming LiveTemplate tree-based updates, implementing Phoenix LiveView-style optimization.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Tree-based Updates**: Consume optimized JSON updates from LiveTemplate server
8
+ - **Static Structure Caching**: Cache static HTML structure client-side for maximum efficiency
9
+ - **Phoenix LiveView Compatible**: Only dynamic values transmitted after initial render
10
+ - **Bandwidth Optimization**: 75%+ reduction in update payload sizes
11
+ - **Type Safety**: Full TypeScript support with type definitions
12
+
13
+ ## 📦 Installation
14
+
15
+ ```bash
16
+ npm install
17
+ npm run build
18
+ ```
19
+
20
+ ## 🧪 Testing
21
+
22
+ The client includes comprehensive tests to validate the optimization effectiveness:
23
+
24
+ ```bash
25
+ # Run optimization validation tests
26
+ npm run test:optimization
27
+
28
+ # Run HTML reconstruction tests
29
+ npm run test:reconstruction
30
+
31
+ # Run all tests
32
+ npm run test:all
33
+ ```
34
+
35
+ ## 📊 Test Results
36
+
37
+ Current optimization performance:
38
+
39
+ - **Update 1**: 168 bytes (first update after initial render)
40
+ - **Update 2**: 128 bytes (subsequent optimized update)
41
+ - **Bandwidth Savings**: ~75.3% vs full HTML updates
42
+ - **Static Structure**: Successfully excluded from updates ✅
43
+
44
+ ## 🛠️ Usage
45
+
46
+ ### Basic Client Usage
47
+
48
+ ```typescript
49
+ import { LiveTemplateClient } from "./livetemplate-client";
50
+
51
+ const client = new LiveTemplateClient();
52
+
53
+ // Apply initial update (includes static structure)
54
+ const initialResult = client.applyUpdate({
55
+ s: ["<h1>", "</h1><p>Count: ", "</p>"], // Static HTML segments
56
+ "0": "Hello World", // Dynamic content
57
+ "1": "42", // Dynamic content
58
+ });
59
+
60
+ console.log(initialResult.html); // "<h1>Hello World</h1><p>Count: 42</p>"
61
+
62
+ // Apply subsequent update (only changed dynamic values)
63
+ const updateResult = client.applyUpdate({
64
+ "1": "43", // Only the changed value
65
+ });
66
+
67
+ console.log(updateResult.html); // "<h1>Hello World</h1><p>Count: 43</p>"
68
+ console.log(updateResult.changed); // true
69
+ ```
70
+
71
+ ### Loading Updates from Files
72
+
73
+ ```typescript
74
+ import { loadAndApplyUpdate } from "./livetemplate-client";
75
+
76
+ const client = new LiveTemplateClient();
77
+
78
+ // Load update from JSON file
79
+ const result = await loadAndApplyUpdate(client, "update_01.json");
80
+ console.log(result.html);
81
+ ```
82
+
83
+ ### HTML Comparison
84
+
85
+ ```typescript
86
+ import { compareHTML } from "./livetemplate-client";
87
+
88
+ const comparison = compareHTML(expectedHTML, actualHTML);
89
+ if (comparison.match) {
90
+ console.log("✅ HTML matches!");
91
+ } else {
92
+ console.log("❌ Differences found:", comparison.differences);
93
+ }
94
+ ```
95
+
96
+ ## 🏗️ Architecture
97
+
98
+ ### Tree-Based Updates
99
+
100
+ LiveTemplate uses a tree-based approach where:
101
+
102
+ 1. **Static Structure** (`"s"` key): HTML segments sent once and cached client-side
103
+ 2. **Dynamic Values** (numbered keys): Only the values that change between updates
104
+ 3. **Segment Interleaving**: Client reconstructs HTML by interleaving static + dynamic
105
+
106
+ Example update structure:
107
+
108
+ ```json
109
+ {
110
+ "s": ["<h1>", "</h1><div>Count: ", "</div>"], // Static HTML (sent once)
111
+ "0": "Task Manager", // Dynamic: page title
112
+ "1": "42" // Dynamic: counter value
113
+ }
114
+ ```
115
+
116
+ ### Optimization Strategy
117
+
118
+ Following Phoenix LiveView's approach:
119
+
120
+ - **Initial Render**: Full HTML + cached static structure
121
+ - **Subsequent Updates**: Only changed dynamic values (75%+ bandwidth savings)
122
+ - **Client Reconstruction**: Merge updates with cached structure
123
+ - **DOM Morphing**: Let morphdom handle efficient DOM updates
124
+
125
+ ## 🧪 Test Data
126
+
127
+ The test suite validates optimization using real E2E test data:
128
+
129
+ - `testdata/e2e/update_01_add_todos.json` - First optimized update (168 bytes)
130
+ - `testdata/e2e/update_02_remove_todo.json` - Subsequent update (128 bytes)
131
+ - `testdata/e2e/rendered_*.html` - Expected HTML output for comparison
132
+
133
+ ## 🔧 API Reference
134
+
135
+ ### LiveTemplateClient
136
+
137
+ #### `applyUpdate(update: TreeNode): UpdateResult`
138
+
139
+ Apply a tree-based update to the client state.
140
+
141
+ - **Parameters**: `update` - Tree update object from LiveTemplate server
142
+ - **Returns**: `{ html: string, changed: boolean }`
143
+
144
+ #### `reset(): void`
145
+
146
+ Reset client state (useful for testing).
147
+
148
+ #### `getState(): { static: string[] | null, dynamic: object }`
149
+
150
+ Get current cached state for debugging.
151
+
152
+ ### Utility Functions
153
+
154
+ #### `loadAndApplyUpdate(client, path): Promise<UpdateResult>`
155
+
156
+ Load update from JSON file and apply to client.
157
+
158
+ #### `compareHTML(expected, actual): { match: boolean, differences: string[] }`
159
+
160
+ Compare two HTML strings, ignoring whitespace differences.
161
+
162
+ ## 🚀 Performance
163
+
164
+ Optimization results with real E2E test data:
165
+
166
+ | Update Type | Size (bytes) | Bandwidth Savings |
167
+ | ------------ | ------------ | ----------------- |
168
+ | Full HTML | ~600 | 0% (baseline) |
169
+ | Optimized #1 | 168 | 72% |
170
+ | Optimized #2 | 128 | 79% |
171
+ | **Average** | **148** | **~75.3%** |
172
+
173
+ ## 📈 Future Enhancements
174
+
175
+ - Browser-based DOM morphing integration
176
+ - WebSocket client for real-time updates
177
+ - React/Vue.js integration hooks
178
+ - Advanced diff algorithms for complex nested structures
179
+ - Performance monitoring and metrics
@@ -0,0 +1,2 @@
1
+ export declare const FOCUSABLE_INPUTS: string[];
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,UAc5B,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FOCUSABLE_INPUTS = void 0;
4
+ exports.FOCUSABLE_INPUTS = [
5
+ "text",
6
+ "textarea",
7
+ "number",
8
+ "email",
9
+ "password",
10
+ "search",
11
+ "tel",
12
+ "url",
13
+ "date",
14
+ "time",
15
+ "datetime-local",
16
+ "color",
17
+ "range",
18
+ ];
19
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC9B,MAAM;IACN,UAAU;IACV,QAAQ;IACR,OAAO;IACP,UAAU;IACV,QAAQ;IACR,KAAK;IACL,KAAK;IACL,MAAM;IACN,MAAM;IACN,gBAAgB;IAChB,OAAO;IACP,OAAO;CACR,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Apply scroll directives on elements with lvt-scroll attributes.
3
+ */
4
+ export declare function handleScrollDirectives(rootElement: Element): void;
5
+ /**
6
+ * Apply highlight directives to elements with lvt-highlight attributes.
7
+ */
8
+ export declare function handleHighlightDirectives(rootElement: Element): void;
9
+ /**
10
+ * Apply animation directives to elements with lvt-animate attributes.
11
+ */
12
+ export declare function handleAnimateDirectives(rootElement: Element): void;
13
+ //# sourceMappingURL=directives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directives.d.ts","sourceRoot":"","sources":["../../dom/directives.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAqDjE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CA4BpE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAyElE"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleScrollDirectives = handleScrollDirectives;
4
+ exports.handleHighlightDirectives = handleHighlightDirectives;
5
+ exports.handleAnimateDirectives = handleAnimateDirectives;
6
+ /**
7
+ * Apply scroll directives on elements with lvt-scroll attributes.
8
+ */
9
+ function handleScrollDirectives(rootElement) {
10
+ const scrollElements = rootElement.querySelectorAll("[lvt-scroll]");
11
+ scrollElements.forEach((element) => {
12
+ const htmlElement = element;
13
+ const mode = htmlElement.getAttribute("lvt-scroll");
14
+ const behavior = htmlElement.getAttribute("lvt-scroll-behavior") ||
15
+ "auto";
16
+ const threshold = parseInt(htmlElement.getAttribute("lvt-scroll-threshold") || "100", 10);
17
+ if (!mode)
18
+ return;
19
+ switch (mode) {
20
+ case "bottom":
21
+ htmlElement.scrollTo({
22
+ top: htmlElement.scrollHeight,
23
+ behavior,
24
+ });
25
+ break;
26
+ case "bottom-sticky": {
27
+ const isNearBottom = htmlElement.scrollHeight -
28
+ htmlElement.scrollTop -
29
+ htmlElement.clientHeight <=
30
+ threshold;
31
+ if (isNearBottom) {
32
+ htmlElement.scrollTo({
33
+ top: htmlElement.scrollHeight,
34
+ behavior,
35
+ });
36
+ }
37
+ break;
38
+ }
39
+ case "top":
40
+ htmlElement.scrollTo({
41
+ top: 0,
42
+ behavior,
43
+ });
44
+ break;
45
+ case "preserve":
46
+ break;
47
+ default:
48
+ console.warn(`Unknown lvt-scroll mode: ${mode}`);
49
+ }
50
+ });
51
+ }
52
+ /**
53
+ * Apply highlight directives to elements with lvt-highlight attributes.
54
+ */
55
+ function handleHighlightDirectives(rootElement) {
56
+ const highlightElements = rootElement.querySelectorAll("[lvt-highlight]");
57
+ highlightElements.forEach((element) => {
58
+ const mode = element.getAttribute("lvt-highlight");
59
+ const duration = parseInt(element.getAttribute("lvt-highlight-duration") || "500", 10);
60
+ const color = element.getAttribute("lvt-highlight-color") || "#ffc107";
61
+ if (!mode)
62
+ return;
63
+ const htmlElement = element;
64
+ const originalBackground = htmlElement.style.backgroundColor;
65
+ const originalTransition = htmlElement.style.transition;
66
+ htmlElement.style.transition = `background-color ${duration}ms ease-out`;
67
+ htmlElement.style.backgroundColor = color;
68
+ setTimeout(() => {
69
+ htmlElement.style.backgroundColor = originalBackground;
70
+ setTimeout(() => {
71
+ htmlElement.style.transition = originalTransition;
72
+ }, duration);
73
+ }, 50);
74
+ });
75
+ }
76
+ /**
77
+ * Apply animation directives to elements with lvt-animate attributes.
78
+ */
79
+ function handleAnimateDirectives(rootElement) {
80
+ const animateElements = rootElement.querySelectorAll("[lvt-animate]");
81
+ animateElements.forEach((element) => {
82
+ const animation = element.getAttribute("lvt-animate");
83
+ const duration = parseInt(element.getAttribute("lvt-animate-duration") || "300", 10);
84
+ if (!animation)
85
+ return;
86
+ const htmlElement = element;
87
+ htmlElement.style.setProperty("--lvt-animate-duration", `${duration}ms`);
88
+ switch (animation) {
89
+ case "fade":
90
+ htmlElement.style.animation = `lvt-fade-in var(--lvt-animate-duration) ease-out`;
91
+ break;
92
+ case "slide":
93
+ htmlElement.style.animation = `lvt-slide-in var(--lvt-animate-duration) ease-out`;
94
+ break;
95
+ case "scale":
96
+ htmlElement.style.animation = `lvt-scale-in var(--lvt-animate-duration) ease-out`;
97
+ break;
98
+ default:
99
+ console.warn(`Unknown lvt-animate mode: ${animation}`);
100
+ }
101
+ htmlElement.addEventListener("animationend", () => {
102
+ htmlElement.style.animation = "";
103
+ }, { once: true });
104
+ });
105
+ if (!document.getElementById("lvt-animate-styles")) {
106
+ const style = document.createElement("style");
107
+ style.id = "lvt-animate-styles";
108
+ style.textContent = `
109
+ @keyframes lvt-fade-in {
110
+ from { opacity: 0; }
111
+ to { opacity: 1; }
112
+ }
113
+ @keyframes lvt-slide-in {
114
+ from {
115
+ opacity: 0;
116
+ transform: translateY(-10px);
117
+ }
118
+ to {
119
+ opacity: 1;
120
+ transform: translateY(0);
121
+ }
122
+ }
123
+ @keyframes lvt-scale-in {
124
+ from {
125
+ opacity: 0;
126
+ transform: scale(0.95);
127
+ }
128
+ to {
129
+ opacity: 1;
130
+ transform: scale(1);
131
+ }
132
+ }
133
+ `;
134
+ document.head.appendChild(style);
135
+ }
136
+ }
137
+ //# sourceMappingURL=directives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directives.js","sourceRoot":"","sources":["../../dom/directives.ts"],"names":[],"mappings":";;AAGA,wDAqDC;AAKD,8DA4BC;AAKD,0DAyEC;AAvKD;;GAEG;AACH,SAAgB,sBAAsB,CAAC,WAAoB;IACzD,MAAM,cAAc,GAAG,WAAW,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAEpE,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACjC,MAAM,WAAW,GAAG,OAAsB,CAAC;QAC3C,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACpD,MAAM,QAAQ,GACX,WAAW,CAAC,YAAY,CAAC,qBAAqB,CAAoB;YACnE,MAAM,CAAC;QACT,MAAM,SAAS,GAAG,QAAQ,CACxB,WAAW,CAAC,YAAY,CAAC,sBAAsB,CAAC,IAAI,KAAK,EACzD,EAAE,CACH,CAAC;QAEF,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,QAAQ;gBACX,WAAW,CAAC,QAAQ,CAAC;oBACnB,GAAG,EAAE,WAAW,CAAC,YAAY;oBAC7B,QAAQ;iBACT,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,YAAY,GAChB,WAAW,CAAC,YAAY;oBACtB,WAAW,CAAC,SAAS;oBACrB,WAAW,CAAC,YAAY;oBAC1B,SAAS,CAAC;gBACZ,IAAI,YAAY,EAAE,CAAC;oBACjB,WAAW,CAAC,QAAQ,CAAC;wBACnB,GAAG,EAAE,WAAW,CAAC,YAAY;wBAC7B,QAAQ;qBACT,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,KAAK;gBACR,WAAW,CAAC,QAAQ,CAAC;oBACnB,GAAG,EAAE,CAAC;oBACN,QAAQ;iBACT,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,UAAU;gBACb,MAAM;YAER;gBACE,OAAO,CAAC,IAAI,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,yBAAyB,CAAC,WAAoB;IAC5D,MAAM,iBAAiB,GAAG,WAAW,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;IAE1E,iBAAiB,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,QAAQ,CACvB,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC,IAAI,KAAK,EACvD,EAAE,CACH,CAAC;QACF,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,qBAAqB,CAAC,IAAI,SAAS,CAAC;QAEvE,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAM,WAAW,GAAG,OAAsB,CAAC;QAC3C,MAAM,kBAAkB,GAAG,WAAW,CAAC,KAAK,CAAC,eAAe,CAAC;QAC7D,MAAM,kBAAkB,GAAG,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;QAExD,WAAW,CAAC,KAAK,CAAC,UAAU,GAAG,oBAAoB,QAAQ,aAAa,CAAC;QACzE,WAAW,CAAC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC;QAE1C,UAAU,CAAC,GAAG,EAAE;YACd,WAAW,CAAC,KAAK,CAAC,eAAe,GAAG,kBAAkB,CAAC;YAEvD,UAAU,CAAC,GAAG,EAAE;gBACd,WAAW,CAAC,KAAK,CAAC,UAAU,GAAG,kBAAkB,CAAC;YACpD,CAAC,EAAE,QAAQ,CAAC,CAAC;QACf,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,WAAoB;IAC1D,MAAM,eAAe,GAAG,WAAW,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAEtE,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,QAAQ,CACvB,OAAO,CAAC,YAAY,CAAC,sBAAsB,CAAC,IAAI,KAAK,EACrD,EAAE,CACH,CAAC;QAEF,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,WAAW,GAAG,OAAsB,CAAC;QAE3C,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,wBAAwB,EAAE,GAAG,QAAQ,IAAI,CAAC,CAAC;QAEzE,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,MAAM;gBACT,WAAW,CAAC,KAAK,CAAC,SAAS,GAAG,kDAAkD,CAAC;gBACjF,MAAM;YAER,KAAK,OAAO;gBACV,WAAW,CAAC,KAAK,CAAC,SAAS,GAAG,mDAAmD,CAAC;gBAClF,MAAM;YAER,KAAK,OAAO;gBACV,WAAW,CAAC,KAAK,CAAC,SAAS,GAAG,mDAAmD,CAAC;gBAClF,MAAM;YAER;gBACE,OAAO,CAAC,IAAI,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,WAAW,CAAC,gBAAgB,CAC1B,cAAc,EACd,GAAG,EAAE;YACH,WAAW,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC;QACnC,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,EAAE,GAAG,oBAAoB,CAAC;QAChC,KAAK,CAAC,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;KAyBnB,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Logger } from "../utils/logger";
2
+ export interface EventDelegationContext {
3
+ getWrapperElement(): Element | null;
4
+ getRateLimitedHandlers(): WeakMap<Element, Map<string, Function>>;
5
+ parseValue(value: string): any;
6
+ send(message: any): void;
7
+ setActiveSubmission(form: HTMLFormElement | null, button: HTMLButtonElement | null, originalButtonText: string | null): void;
8
+ openModal(modalId: string): void;
9
+ closeModal(modalId: string): void;
10
+ getWebSocketReadyState(): number | undefined;
11
+ }
12
+ /**
13
+ * Handles all DOM event delegation concerns for LiveTemplateClient.
14
+ */
15
+ export declare class EventDelegator {
16
+ private readonly context;
17
+ private readonly logger;
18
+ constructor(context: EventDelegationContext, logger: Logger);
19
+ setupEventDelegation(): void;
20
+ setupWindowEventDelegation(): void;
21
+ setupClickAwayDelegation(): void;
22
+ setupModalDelegation(): void;
23
+ }
24
+ //# sourceMappingURL=event-delegation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-delegation.d.ts","sourceRoot":"","sources":["../../dom/event-delegation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,iBAAiB,IAAI,OAAO,GAAG,IAAI,CAAC;IACpC,sBAAsB,IAAI,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClE,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IACzB,mBAAmB,CACjB,IAAI,EAAE,eAAe,GAAG,IAAI,EAC5B,MAAM,EAAE,iBAAiB,GAAG,IAAI,EAChC,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,IAAI,CAAC;IACR,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAAC;CAC9C;AAED;;GAEG;AACH,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,MAAM;IAGjC,oBAAoB,IAAI,IAAI;IAmR5B,0BAA0B,IAAI,IAAI;IAoGlC,wBAAwB,IAAI,IAAI;IAgDhC,oBAAoB,IAAI,IAAI;CAkG7B"}