@dooboostore/simple-web-component 1.0.37 → 1.0.38

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 (156) hide show
  1. package/README.md +384 -93
  2. package/dist/cjs/SwcAppEngine.js +3 -0
  3. package/dist/cjs/SwcAppEngine.js.map +2 -2
  4. package/dist/cjs/decorators/addEventListener.js +20 -4
  5. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  6. package/dist/cjs/decorators/applyAttribute.js.map +1 -1
  7. package/dist/cjs/decorators/applyClass.js.map +1 -1
  8. package/dist/cjs/decorators/applyNode.js +97 -15
  9. package/dist/cjs/decorators/applyNode.js.map +2 -2
  10. package/dist/cjs/decorators/applySlot.js +16 -9
  11. package/dist/cjs/decorators/applySlot.js.map +2 -2
  12. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  13. package/dist/cjs/decorators/attribute.js.map +1 -1
  14. package/dist/cjs/decorators/elementDefine.js +68 -38
  15. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  16. package/dist/cjs/decorators/emitCustomEvent.js.map +1 -1
  17. package/dist/cjs/decorators/index.js +1 -0
  18. package/dist/cjs/decorators/index.js.map +2 -2
  19. package/dist/cjs/decorators/lifecycles.js +47 -31
  20. package/dist/cjs/decorators/lifecycles.js.map +3 -3
  21. package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
  22. package/dist/cjs/decorators/query.js +1 -1
  23. package/dist/cjs/decorators/query.js.map +2 -2
  24. package/dist/cjs/decorators/queryAll.js.map +1 -1
  25. package/dist/cjs/decorators/setProperty.js.map +1 -1
  26. package/dist/cjs/decorators/state.js +84 -0
  27. package/dist/cjs/decorators/state.js.map +7 -0
  28. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  29. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  30. package/dist/cjs/elements/SwcApp.js +193 -305
  31. package/dist/cjs/elements/SwcApp.js.map +3 -3
  32. package/dist/cjs/elements/SwcAppMixin.js +291 -0
  33. package/dist/cjs/elements/SwcAppMixin.js.map +7 -0
  34. package/dist/cjs/elements/index.js +3 -21
  35. package/dist/cjs/elements/index.js.map +3 -3
  36. package/dist/cjs/index.js +1 -3
  37. package/dist/cjs/index.js.map +2 -2
  38. package/dist/cjs/{types.js → types/index.js} +1 -1
  39. package/dist/cjs/types/index.js.map +7 -0
  40. package/dist/cjs/types/window.d.js.map +1 -1
  41. package/dist/cjs/utils/Utils.js +159 -20
  42. package/dist/cjs/utils/Utils.js.map +3 -3
  43. package/dist/esm/SwcAppEngine.js +3 -0
  44. package/dist/esm/SwcAppEngine.js.map +2 -2
  45. package/dist/esm/decorators/addEventListener.js +20 -4
  46. package/dist/esm/decorators/addEventListener.js.map +2 -2
  47. package/dist/esm/decorators/applyAttribute.js.map +1 -1
  48. package/dist/esm/decorators/applyClass.js.map +1 -1
  49. package/dist/esm/decorators/applyNode.js +97 -15
  50. package/dist/esm/decorators/applyNode.js.map +2 -2
  51. package/dist/esm/decorators/applySlot.js +16 -9
  52. package/dist/esm/decorators/applySlot.js.map +2 -2
  53. package/dist/esm/decorators/applyStyle.js.map +2 -2
  54. package/dist/esm/decorators/attribute.js.map +1 -1
  55. package/dist/esm/decorators/elementDefine.js +72 -42
  56. package/dist/esm/decorators/elementDefine.js.map +2 -2
  57. package/dist/esm/decorators/emitCustomEvent.js.map +1 -1
  58. package/dist/esm/decorators/index.js +1 -0
  59. package/dist/esm/decorators/index.js.map +2 -2
  60. package/dist/esm/decorators/lifecycles.js +47 -31
  61. package/dist/esm/decorators/lifecycles.js.map +3 -3
  62. package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
  63. package/dist/esm/decorators/query.js +1 -1
  64. package/dist/esm/decorators/query.js.map +2 -2
  65. package/dist/esm/decorators/queryAll.js.map +1 -1
  66. package/dist/esm/decorators/setProperty.js.map +1 -1
  67. package/dist/esm/decorators/state.js +65 -0
  68. package/dist/esm/decorators/state.js.map +7 -0
  69. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  70. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  71. package/dist/esm/elements/SwcApp.js +195 -307
  72. package/dist/esm/elements/SwcApp.js.map +3 -3
  73. package/dist/esm/elements/SwcAppMixin.js +273 -0
  74. package/dist/esm/elements/SwcAppMixin.js.map +7 -0
  75. package/dist/esm/elements/index.js +2 -7
  76. package/dist/esm/elements/index.js.map +2 -2
  77. package/dist/esm/index.js +2 -4
  78. package/dist/esm/index.js.map +2 -2
  79. package/dist/esm/{types.js → types/index.js} +1 -1
  80. package/dist/esm/types/index.js.map +7 -0
  81. package/dist/esm/utils/Utils.js +159 -20
  82. package/dist/esm/utils/Utils.js.map +3 -3
  83. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +3356 -2477
  84. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  85. package/dist/types/SwcAppEngine.d.ts +1 -1
  86. package/dist/types/SwcAppEngine.d.ts.map +1 -1
  87. package/dist/types/decorators/addEventListener.d.ts +5 -2
  88. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  89. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  90. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  91. package/dist/types/decorators/applyNode.d.ts +22 -6
  92. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  93. package/dist/types/decorators/applySlot.d.ts.map +1 -1
  94. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  95. package/dist/types/decorators/attribute.d.ts.map +1 -1
  96. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  97. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  98. package/dist/types/decorators/index.d.ts +1 -0
  99. package/dist/types/decorators/index.d.ts.map +1 -1
  100. package/dist/types/decorators/lifecycles.d.ts +10 -14
  101. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  102. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
  103. package/dist/types/decorators/query.d.ts +1 -1
  104. package/dist/types/decorators/query.d.ts.map +1 -1
  105. package/dist/types/decorators/queryAll.d.ts.map +1 -1
  106. package/dist/types/decorators/setProperty.d.ts +1 -1
  107. package/dist/types/decorators/setProperty.d.ts.map +1 -1
  108. package/dist/types/decorators/state.d.ts +9 -0
  109. package/dist/types/decorators/state.d.ts.map +1 -0
  110. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  111. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +5 -1
  112. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  113. package/dist/types/elements/SwcApp.d.ts +35 -6
  114. package/dist/types/elements/SwcApp.d.ts.map +1 -1
  115. package/dist/types/elements/SwcAppMixin.d.ts +405 -0
  116. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -0
  117. package/dist/types/elements/index.d.ts +2 -2
  118. package/dist/types/elements/index.d.ts.map +1 -1
  119. package/dist/types/index.d.ts +1 -1
  120. package/dist/types/index.d.ts.map +1 -1
  121. package/dist/types/{types.d.ts → types/index.d.ts} +11 -11
  122. package/dist/types/types/index.d.ts.map +1 -0
  123. package/dist/types/utils/Utils.d.ts +14 -2
  124. package/dist/types/utils/Utils.d.ts.map +1 -1
  125. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +3358 -2479
  126. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  127. package/package.json +4 -4
  128. package/src/SwcAppEngine.ts +6 -2
  129. package/src/decorators/addEventListener.ts +21 -5
  130. package/src/decorators/applyAttribute.ts +1 -1
  131. package/src/decorators/applyClass.ts +1 -1
  132. package/src/decorators/applyNode.ts +180 -62
  133. package/src/decorators/applySlot.ts +27 -67
  134. package/src/decorators/applyStyle.ts +4 -4
  135. package/src/decorators/attribute.ts +1 -1
  136. package/src/decorators/elementDefine.ts +110 -58
  137. package/src/decorators/emitCustomEvent.ts +1 -1
  138. package/src/decorators/index.ts +2 -0
  139. package/src/decorators/lifecycles.ts +50 -26
  140. package/src/decorators/publishSwcAppMessage.ts +2 -3
  141. package/src/decorators/query.ts +4 -4
  142. package/src/decorators/queryAll.ts +1 -1
  143. package/src/decorators/setProperty.ts +1 -1
  144. package/src/decorators/state.ts +84 -0
  145. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +1 -1
  146. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +4 -3
  147. package/src/elements/SwcApp.ts +239 -441
  148. package/src/elements/SwcAppMixin.ts +328 -0
  149. package/src/elements/index.ts +2 -9
  150. package/src/index.ts +2 -4
  151. package/src/{types.ts → types/index.ts} +13 -10
  152. package/src/types/window.d.ts +3 -0
  153. package/src/utils/Utils.ts +205 -20
  154. package/dist/cjs/types.js.map +0 -7
  155. package/dist/esm/types.js.map +0 -7
  156. package/dist/types/types.d.ts.map +0 -1
package/README.md CHANGED
@@ -67,44 +67,223 @@ Replace child nodes with new content.
67
67
  replaceChildren(node: Node) {
68
68
  return node;
69
69
  }
70
- ```
70
+ ### 3.5 **Slot Management with @applySlot**
71
+
72
+ Manage dynamic content insertion into named slots using the `@applySlot` decorator. Slots are placeholders in templates that can be updated dynamically.
71
73
 
72
- ### slot
73
74
  ```typescript
74
- @applySlot('zzz')
75
- nodeSlot!: NodeSlot;
75
+ @elementDefine('content-manager')
76
+ class ContentManager extends HTMLElement {
77
+ // Property: Get NodeSlot instance for manual slot manipulation
78
+ @applySlot('main-content')
79
+ mainSlot?: NodeSlot;
80
+
81
+ @applySlot('sidebar')
82
+ sidebarSlot?: NodeSlot;
83
+
84
+ // Method: Replace children in slot with HTML
85
+ @addEventListener('.update-btn', 'click')
86
+ @applySlotReplaceChildren('main-content')
87
+ updateContent() {
88
+ return '<div>Updated content here</div>';
89
+ }
76
90
 
77
- @addEventListener('.test-btn', 'click' )
78
- @applySlotReplaceChildren('zzz')
79
- ttt() {
80
- return '<div>zzzzzzzzzz</div>'
81
- }
91
+ // Method: Append HTML to slot
92
+ @applySlotAppendHtml('main-content')
93
+ addMoreContent() {
94
+ return '<p>Additional content</p>';
95
+ }
82
96
 
83
- @addEventListener('.test-clear-btn', 'click' )
84
- // @applySlot('zzz', {position: 'clear'})
85
- @applySlotClear('zzz')
86
- ttct() {
87
- return true;
88
- }
97
+ // Method: Append text to slot
98
+ @applySlotAppendText('sidebar')
99
+ addSidebarText() {
100
+ return 'Sidebar text: ' + new Date().toISOString();
101
+ }
89
102
 
90
- @onConnectedAfter
91
- ttttt() {
92
- console.log('vvvvvvvvvvvvvvv??', this.nodeSlot)
93
- this.nodeSlot.appendText('zzz22zzz'+new Date().toISOString())
103
+ // Method: Clear slot content
104
+ @addEventListener('.clear-btn', 'click')
105
+ @applySlotClear('main-content')
106
+ clearContent() {
107
+ return true;
108
+ }
109
+
110
+ // Lifecycle: Manual slot manipulation
111
+ @onConnectedAfter
112
+ setupSlots() {
113
+ // Access slot via property for manual manipulation
114
+ if (this.mainSlot) {
115
+ this.mainSlot.appendText('main-content', 'Initial text');
116
+ }
117
+ }
118
+
119
+ @onConnectedInnerHtml
120
+ render() {
121
+ return `
122
+ <div>
123
+ <h2>Main Content</h2>
124
+ <!--[[ main-content ]]-->
125
+
126
+ <aside>
127
+ <h3>Sidebar</h3>
128
+ <!--[[ sidebar ]]-->
129
+ </aside>
130
+
131
+ <button class="update-btn">Update Content</button>
132
+ <button class="clear-btn">Clear Content</button>
133
+ </div>
134
+ `;
135
+ }
94
136
  }
95
- @onConnectedInnerHtml
96
- render()
97
- {
98
-
99
- return `
100
- [[ zzz ]]
101
- <button class="test-btn">test222222222222222</button>
102
- <button class="test-clear-btn">clear</button>
103
- [[ zzz ]]
104
- `
137
+ ```
138
+
139
+ **Slot Syntax in Templates:**
140
+ - `<!--[[ slot-id ]]-->` - Named slot placeholder (HTML comment syntax)
141
+
142
+ **@applySlot Decorator Variants:**
143
+ - `@applySlot(id, options)` - Generic slot operation with position option
144
+ - `@applySlotReplaceChildren(id)` - Replace all children with HTML
145
+ - `@applySlotReplaceChildrenText(id)` - Replace all children with text
146
+ - `@applySlotAppendHtml(id)` - Append HTML to slot
147
+ - `@applySlotAppendText(id)` - Append text to slot
148
+ - `@applySlotPrependHtml(id)` - Prepend HTML to slot
149
+ - `@applySlotPrependText(id)` - Prepend text to slot
150
+ - `@applySlotClear(id)` - Clear slot content
151
+
152
+ **Position Options:**
153
+ ```typescript
154
+ export type ApplySlotPosition =
155
+ | 'prependHtml' // Add HTML at beginning
156
+ | 'prependText' // Add text at beginning
157
+ | 'appendHtml' // Add HTML at end
158
+ | 'appendText' // Add text at end
159
+ | 'replaceChildrenHtml' // Replace all with HTML
160
+ | 'replaceChildrenText' // Replace all with text
161
+ | 'clear'; // Clear all content
162
+ ```
163
+
164
+ **Manual Slot Manipulation:**
165
+ ```typescript
166
+ // Via @applySlot property
167
+ @applySlot('content')
168
+ contentSlot?: NodeSlot;
169
+
170
+ // In lifecycle or methods
171
+ this.contentSlot?.appendHtml('content', '<p>New content</p>');
172
+ this.contentSlot?.appendText('content', 'Text content');
173
+ this.contentSlot?.replaceChildrenHtml('content', '<div>Replaced</div>');
174
+ this.contentSlot?.clear('content');
175
+ ```
176
+
177
+ ### 3.6 **State Management with @state**
178
+
179
+ Reactive state management with automatic DOM updates when state changes. State values are accessible in templates and scripts using special syntax.
180
+
181
+ ```typescript
182
+ @elementDefine('counter-app')
183
+ class CounterApp extends HTMLElement {
184
+ // Declare reactive state
185
+ @state('count')
186
+ count: number = 0;
187
+
188
+ @state('message')
189
+ message: string = 'Hello';
190
+
191
+ @state('isActive')
192
+ isActive: boolean = false;
193
+
194
+ @addEventListener('button', 'click')
195
+ increment() {
196
+ this.count++; // Triggers automatic DOM update
197
+ }
198
+
199
+ @onConnectedInnerHtml
200
+ render() {
201
+ return `
202
+ <div>
203
+ <!-- HTML directive: render HTML content -->
204
+ <!--[html @message@ ]-->
205
+
206
+ <!-- Text directive: render as text -->
207
+ <!--[text Count: @count@ ]-->
208
+
209
+ <!-- Attribute binding with a: prefix -->
210
+ <div a:title="Count is @count@"></div>
211
+
212
+ <!-- Event binding with e: prefix -->
213
+ <button e:click="increment">Increment (@count@)</button>
214
+
215
+ <!-- Conditional rendering -->
216
+ <div a:style="@isActive@ ? 'color: green' : 'color: red'">
217
+ Status: @isActive@
218
+ </div>
219
+ </div>
220
+ `;
221
+ }
105
222
  }
106
223
  ```
107
224
 
225
+ **State Syntax in Templates:**
226
+
227
+ **Reading State Values:**
228
+ - `@stateName@` - Read state value as text/attribute
229
+ - `@stateName@()` - Call state property as function (if it's a function)
230
+ - `@expression@` - Evaluate expressions with state variables
231
+
232
+ **Template Directives:**
233
+ - `<!--[html @state@ ]-->` - Render state value as HTML
234
+ - `<!--[text @state@ ]-->` - Render state value as text
235
+ - `a:attributeName="@state@"` - Bind state to HTML attributes
236
+ - `e:eventName="methodName"` - Bind events to methods
237
+
238
+ **How @state Works:**
239
+ 1. Declare property with `@state('stateName')`
240
+ 2. When property value changes via `this.count++`, setter is triggered
241
+ 3. Setter automatically applies state context to templates
242
+ 4. All `@stateName@` expressions in templates are re-evaluated
243
+ 5. DOM updates automatically with new values
244
+
245
+ **State Context Available:**
246
+ - `@propertyName@` - Access state properties
247
+ - `@methodName@()` - Call methods
248
+ - `@expression@` - Evaluate JavaScript expressions
249
+ - All state variables available in template expressions
250
+
251
+ **Advanced Example:**
252
+ ```typescript
253
+ @elementDefine('user-profile')
254
+ class UserProfile extends HTMLElement {
255
+ @state('user')
256
+ user = { name: 'Alice', age: 30, email: 'alice@example.com' };
257
+
258
+ @state('isEditing')
259
+ isEditing = false;
260
+
261
+ @addEventListener('.edit-btn', 'click')
262
+ toggleEdit() {
263
+ this.isEditing = !this.isEditing;
264
+ }
265
+
266
+ @onConnectedInnerHtml
267
+ render() {
268
+ return `
269
+ <div>
270
+ <!-- Display user info -->
271
+ <h2><!--[text @user.name@ ]--></h2>
272
+ <p a:title="Email: @user.email@">Age: @user.age@</p>
273
+
274
+ <!-- Conditional rendering based on state -->
275
+ <div a:style="@isEditing@ ? 'border: 1px solid blue' : 'border: none'">
276
+ <!--[html @isEditing@ ? '<input type="text" />' : '<span>View Mode</span>' ]-->
277
+ </div>
278
+
279
+ <button e:click="toggleEdit">
280
+ @isEditing@ ? 'Save' : 'Edit'
281
+ </button>
282
+ </div>
283
+ `;
284
+ }
285
+ }
286
+ ```
108
287
 
109
288
  ### 4. **Event Handling**
110
289
 
@@ -624,63 +803,6 @@ class CustomLoop extends HTMLElement {
624
803
 
625
804
  ---
626
805
 
627
- #### 8.5 **Declarative Routing with swc-choose**
628
-
629
- Combine `@subscribeSwcAppRouteChangeWhileConnected` with `swc-choose` for clean, declarative routing without boilerplate.
630
-
631
- ```typescript
632
- @elementDefine('root-router')
633
- class RootRouter extends HTMLElement {
634
- private router: Router;
635
-
636
- @onInitialize
637
- onconstructor(router: Router) {
638
- this.router = router;
639
- }
640
-
641
- @setProperty('#router', 'value')
642
- @subscribeSwcAppRouteChangeWhileConnected(['/', '/users', '/users/{id}', '/products/{id}'])
643
- routeChanged(route: RouterEventType) {
644
- return route;
645
- }
646
-
647
- navigate(path: string): void {
648
- this.router?.go(path);
649
- }
650
-
651
- @onConnectedInnerHtml
652
- render() {
653
- return `
654
- <template id="router" is="swc-choose">
655
- <template is="swc-when" test="['', '/'].includes($value?.path)">
656
- <home-page/>
657
- </template>
658
-
659
- <!-- Users List Page -->
660
- <template is="swc-when" test="$value?.path === '/users'">
661
- <users-list-page/>
662
- </template>
663
-
664
- <!-- User Detail Page: Using {{= }} for dynamic attributes from route params -->
665
- <template is="swc-when" test="$value?.path.startsWith('/users/')">
666
- <user-detail-page user-id="{{= $value?.pathData?.id }}"></user-detail-page>
667
- </template>
668
-
669
- <!-- Product Detail Page: Using {{= }} for dynamic route parameters -->
670
- <template is="swc-when" test="$value?.path.startsWith('/products/')">
671
- <product-detail-page product-id="{{= $value?.pathData?.id }}"></product-detail-page>
672
- </template>
673
-
674
- <!-- Not Found -->
675
- <template is="swc-otherwise">
676
- <not-found-page/>
677
- </template>
678
- </template>
679
- `;
680
- }
681
- }
682
- ```
683
-
684
806
  **Benefits:**
685
807
  - ✅ **No imperative route methods** - routes are declarative templates
686
808
  - ✅ **Automatic re-rendering** - attributes like `user-id` update automatically
@@ -783,7 +905,145 @@ class ProductDetail extends HTMLElement {
783
905
 
784
906
  ---
785
907
 
786
- ### 10. **Accommodation Pattern**
908
+ ### 10. **SwcApp - Multiple Element Types with Mixin Pattern**
909
+
910
+ SWC provides a flexible Mixin-based architecture for creating SwcApp elements that extend different HTMLElement types. This enables building SPAs with any semantic HTML element as the root.
911
+
912
+ #### Available SwcApp Variants
913
+
914
+ ```typescript
915
+ import {
916
+ SwcApp, // swc-app (HTMLElement)
917
+ SwcAppBody, // swc-app-body (HTMLBodyElement, is="body")
918
+ SwcAppDiv, // swc-app-div (HTMLDivElement, is="div")
919
+ SwcAppSection, // swc-app-section (HTMLElement, is="section")
920
+ SwcAppMain, // swc-app-main (HTMLElement, is="main")
921
+ SwcAppArticle, // swc-app-article (HTMLElement, is="article")
922
+ SwcAppHeader, // swc-app-header (HTMLElement, is="header")
923
+ SwcAppFooter, // swc-app-footer (HTMLElement, is="footer")
924
+ SwcAppNav, // swc-app-nav (HTMLElement, is="nav")
925
+ SwcAppAside, // swc-app-aside (HTMLElement, is="aside")
926
+ defineSwcAppAll, // Register all SwcApp variants at once
927
+ swcAppFactories // Array of all definition functions
928
+ } from '@dooboostore/simple-web-component';
929
+ ```
930
+
931
+ #### Using SwcAppBody (Recommended for SPAs)
932
+
933
+ ```html
934
+ <!DOCTYPE html>
935
+ <html>
936
+ <head>
937
+ <meta charset="UTF-8">
938
+ <title>My SPA</title>
939
+ </head>
940
+ <!-- Use is="swc-app-body" for semantic HTML -->
941
+ <body id="app" is="swc-app-body">
942
+ <root-router></root-router>
943
+ </body>
944
+ <script src="bundle.js"></script>
945
+ </html>
946
+ ```
947
+
948
+ ```typescript
949
+ // index.ts
950
+ import 'reflect-metadata';
951
+ import { SwcAppInterface, defineSwcAppAll } from '@dooboostore/simple-web-component';
952
+ import bootFactory from './bootFactory';
953
+
954
+ const w = window;
955
+
956
+ w.document.addEventListener('DOMContentLoaded', async () => {
957
+ const container = Symbol('app');
958
+
959
+ // Initialize services and components
960
+ bootFactory(w, container);
961
+
962
+ // Register all SwcApp variants
963
+ await defineSwcAppAll(w);
964
+
965
+ // Get app root element
966
+ const appElement = w.document.querySelector('#app') as SwcAppInterface;
967
+
968
+ if (appElement && typeof appElement.connect === 'function') {
969
+ appElement.connect({
970
+ path: '/',
971
+ routeType: 'path',
972
+ container: container,
973
+ window: w,
974
+ onEngineStarted: () => {
975
+ console.log('🚀 Application started successfully');
976
+ }
977
+ });
978
+ }
979
+ });
980
+ ```
981
+
982
+ #### SwcAppMixin - Reusable Component Logic
983
+
984
+ The `SwcAppMixin` extracts all SwcApp functionality into a reusable mixin that can be applied to any HTMLElement type:
985
+
986
+ ```typescript
987
+ import { SwcAppMixin } from '@dooboostore/simple-web-component';
988
+ import { elementDefine } from '@dooboostore/simple-web-component';
989
+
990
+ // Create custom SwcApp variant extending HTMLDivElement
991
+ @elementDefine('custom-app', { window: w, extends: 'div' })
992
+ class CustomApp extends SwcAppMixin(w.HTMLDivElement) implements SwcAppInterface {
993
+ // All SwcApp functionality inherited from mixin
994
+ // Add custom logic here if needed
995
+ }
996
+ ```
997
+
998
+ #### SwcAppMixin Features
999
+
1000
+ The mixin provides:
1001
+ - **Lifecycle Management**: `connectedCallback`, `disconnectedCallback` with parent class support
1002
+ - **Routing**: `routing(path)`, `back()`, `forward()`, `reload()`
1003
+ - **Message Bus**: `publishMessage()` for inter-component communication
1004
+ - **Route Subscriptions**: Automatic route change handling for connected components
1005
+ - **SSR Support**: `isSSR()`, `setSSRAttribute()`, `removeSSRAttribute()` utilities
1006
+ - **DI Integration**: Full dependency injection support via `@onInitialize`
1007
+
1008
+ #### Factory Pattern - Component Registration
1009
+
1010
+ ```typescript
1011
+ // Component factory
1012
+ export default (w: Window) => {
1013
+ const tagName = 'my-component';
1014
+ const existing = w.customElements.get(tagName);
1015
+ if (existing) return tagName;
1016
+
1017
+ @elementDefine(tagName, { window: w })
1018
+ class MyComponent extends w.HTMLElement {
1019
+ @onInitialize
1020
+ onconstructor(service: MyService) {
1021
+ this.service = service;
1022
+ }
1023
+ }
1024
+
1025
+ return tagName;
1026
+ };
1027
+
1028
+ // Boot factory
1029
+ export default (w: Window, container: symbol) => {
1030
+ serviceFactories.forEach(s => s(container));
1031
+ register(w, [...pageFactories, ...componentFactories]);
1032
+ };
1033
+
1034
+ // Entry point
1035
+ const container = Symbol('app');
1036
+ bootFactory(w, container);
1037
+ appElement.connect({
1038
+ container,
1039
+ window: w,
1040
+ onEngineStarted: () => {
1041
+ appElement.innerHTML = '<root-router></root-router>';
1042
+ }
1043
+ });
1044
+ ```
1045
+
1046
+ ### 11. **Accommodation Pattern**
787
1047
  Factory-based component registration with explicit DI.
788
1048
 
789
1049
  ```typescript
@@ -822,7 +1082,7 @@ appElement.connect({
822
1082
  });
823
1083
  ```
824
1084
 
825
- ### 11. **Quickstart - Basic SPA Setup**
1085
+ ### 12. **Quickstart - Basic SPA Setup**
826
1086
 
827
1087
  Complete example of setting up a production SPA with routing, services, and components.
828
1088
 
@@ -837,6 +1097,7 @@ Complete example of setting up a production SPA with routing, services, and comp
837
1097
  <!-- Web Components polyfill for older browsers -->
838
1098
  <script src="https://unpkg.com/@ungap/custom-elements"></script>
839
1099
  </head>
1100
+ <!-- Use is="swc-app-body" for semantic HTML root -->
840
1101
  <body id="app" is="swc-app-body">
841
1102
  <!-- Root router will render pages here -->
842
1103
  <root-router></root-router>
@@ -941,7 +1202,7 @@ const rootRouterFactory = (w: Window) => {
941
1202
 
942
1203
  <!-- User Detail -->
943
1204
  <template is="swc-when" test="$value?.path.startsWith('/users/')">
944
- <user-detail-page user-id="{{$value?.pathData?.id}}"/>
1205
+ <user-detail-page user-id="{{= $value?.pathData?.id}}"/>
945
1206
  </template>
946
1207
 
947
1208
  <!-- Not Found -->
@@ -1043,7 +1304,7 @@ export default UsersListPage;
1043
1304
  #### Step 4-1. Reusable Components
1044
1305
  ```typescript
1045
1306
  // components/UserCard.ts
1046
- import { elementDefine, onConnectedInnerHtml, attributeHost } from '@dooboostore/simple-web-component';
1307
+ import { elementDefine, onConnectedInnerHtml, attributeThis } from '@dooboostore/simple-web-component';
1047
1308
 
1048
1309
  const UserCard = (w: Window) => {
1049
1310
  const tagName = 'user-card';
@@ -1139,11 +1400,41 @@ export default (w: Window, container: symbol) => {
1139
1400
  ```typescript
1140
1401
  // index.ts
1141
1402
  import 'reflect-metadata';
1142
- import { SwcAppInterface } from '@dooboostore/simple-web-component';
1403
+ import { SwcAppInterface, defineSwcAppAll } from '@dooboostore/simple-web-component';
1143
1404
  import bootFactory from './bootFactory';
1144
1405
 
1145
1406
  const w = window;
1146
1407
 
1408
+ w.document.addEventListener('DOMContentLoaded', async () => {
1409
+ const container = Symbol('app');
1410
+
1411
+ // Initialize services and components
1412
+ bootFactory(w, container);
1413
+
1414
+ // Register all SwcApp variants (swc-app, swc-app-body, swc-app-div, etc.)
1415
+ await defineSwcAppAll(w);
1416
+
1417
+ // Get app root element
1418
+ const appElement = w.document.querySelector('#app') as SwcAppInterface;
1419
+
1420
+ if (appElement && typeof appElement.connect === 'function') {
1421
+ // Connect SPA with routing and DI
1422
+ appElement.connect({
1423
+ path: '/',
1424
+ routeType: 'path',
1425
+ container: container,
1426
+ window: w,
1427
+ onEngineStarted: () => {
1428
+ console.log('🚀 Application started successfully');
1429
+ // Root router automatically initialized via @elementDefine
1430
+ }
1431
+ });
1432
+ } else {
1433
+ console.error('Failed to initialize SPA');
1434
+ }
1435
+ });
1436
+ ```ow;
1437
+
1147
1438
  w.document.addEventListener('DOMContentLoaded', async () => {
1148
1439
  const container = Symbol('app');
1149
1440
 
@@ -1198,11 +1489,11 @@ src/
1198
1489
  1. HTML loads → `<root-router>` element already in DOM
1199
1490
  2. `index.ts` executes → calls `bootFactory`
1200
1491
  3. `bootFactory` registers services and components (including `rootRouterFactory`)
1201
- 4. App waits for `swc-app-body` to be defined
1492
+ 4. App waits for `swc-app-body` to be defined via `defineSwcAppAll()`
1202
1493
  5. `appElement.connect()` initializes routing & DI
1203
1494
  6. `<root-router>` becomes active with `@subscribeSwcAppRouteChangeWhileConnected` + `swc-choose` template
1204
1495
  7. Route changes automatically trigger `swc-choose` re-evaluation and template re-rendering
1205
- 8. Template attributes like `user-id="{{$value?.pathData?.id}}"` are dynamically populated with route params
1496
+ 8. Template attributes like `user-id="{{= $value?.pathData?.id}}"` are dynamically populated with route params
1206
1497
  9. All components have access to injected services via `@onInitialize`
1207
1498
 
1208
1499
 
@@ -59,6 +59,9 @@ class SwcAppEngine {
59
59
  });
60
60
  if (this.router) otherInstanceSim.set(import_core_web.Router, this.router);
61
61
  this.simpleApplication.run(otherInstanceSim);
62
+ if (this._config.onStartedLazyDefineComponent) {
63
+ await Promise.all(this._config.onStartedLazyDefineComponent.map((it) => it(this._config.window)));
64
+ }
62
65
  if (this._config.onEngineStarted) {
63
66
  await this._config.onEngineStarted(this.simpleApplication, this.host);
64
67
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/SwcAppEngine.ts"],
4
- "sourcesContent": ["import { SimpleApplication } from '@dooboostore/simple-boot';\nimport { HashRouter, PathRouter, Router, RouterEventType } from '@dooboostore/core-web';\nimport { ElementRouter } from './router/ElementRouter';\nimport { SimOption } from '@dooboostore/simple-boot';\nimport { ConstructorType, OptionalType, Subscription } from '@dooboostore/core';\n\nimport { SwcAppInterface } from './types';\nimport { SimConfig } from '@dooboostore/simple-boot';\n\nexport type SwcConfigType = {\n routeType: 'path' | 'hash' | 'element';\n connectMode?: 'direct' | 'swap' | 'clear-swap' | 'hydrate'; // hydrate \uC544\uC9C1 \uAC1C\uBC1C\uC911\n container?: symbol;\n otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | symbol, any>;\n path?: string;\n window: Window;\n onEngineStarted?: (sp: SimpleApplication, app: SwcAppInterface) => Promise<void> | void;\n onConnectedChildAfter?: (swcEl: HTMLElement) => void;\n onConnectedChildBefore?: (swcEl: HTMLElement) => void;\n onDisconnectedChildAfter?: (swcEl: HTMLElement) => void;\n onDisconnectedChildBefore?: (swcEl: HTMLElement) => void;\n onConnected?: (app: SwcAppInterface) => void;\n onDisconnected?: (app: SwcAppInterface) => void;\n ssr?: boolean;\n\n onChildrenConnectedDone?: (app: SwcAppInterface) => void;\n // onChildrenSwcAppStartedDone?: (app: SwcAppInterface) => void;\n // childrenSwcAppStartedDoneCheckIntervalTime?: number;\n onChildrenRouteChanged?: (event: RouterEventType, app: SwcAppInterface) => void;\n childrenRouteChangedCheckIntervalTime?: number; // \uC790\uC2DD \uC5F0\uACB0 \uC644\uB8CC \uC774\uBCA4\uD2B8 \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC784 (ms)\n childrenConnectedDoneCheckIntervalTime?: number;\n};\n\nexport type SwcAttributeConfigType = OptionalType<SwcConfigType, 'routeType' | 'window'>;\n\nexport class SwcAppEngine {\n public simpleApplication?: SimpleApplication;\n public router?: Router;\n private routerSubscription?: Subscription;\n private _config?: SwcConfigType;\n\n constructor(private host: HTMLElement) {}\n\n get config() {\n return this._config;\n }\n\n async connect(config: SwcConfigType) {\n try {\n this._config = config;\n\n // Router Selection\n if (this._config.routeType === 'path') {\n this.router = new PathRouter({ window: this._config.window, firstUrl: this._config.path });\n } else if (this._config.routeType === 'hash') {\n this.router = new HashRouter({ window: this._config.window, firstUrl: this._config.path });\n } else if (this._config.routeType === 'element') {\n this.router = new ElementRouter({ window: this._config.window, firstUrl: this._config.path });\n }\n\n // console.log('vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv', this.router)\n\n // App start\n this.simpleApplication = new SimpleApplication(\n new SimOption({\n excludeProxys: [(this._config.window as any).Node],\n container: this._config.container\n })\n );\n\n const otherInstanceSim = new Map<any, any>();\n this.config?.otherInstanceSim?.forEach((v, k) => {\n otherInstanceSim.set(k, v);\n });\n if (this.router) otherInstanceSim.set(Router, this.router);\n this.simpleApplication.run(otherInstanceSim);\n\n if (this._config.onEngineStarted) {\n await this._config.onEngineStarted(this.simpleApplication, this.host as unknown as SwcAppInterface);\n }\n } catch (e) {\n console.error('[SWC-APP-ENGINE] Init failed:', e, this._config);\n }\n }\n\n disconnect() {\n this.routerSubscription?.unsubscribe();\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,sBAAgE;AAChE,2BAA8B;AAC9B,IAAAA,sBAA0B;AAgCnB,MAAM,aAAa;AAAA,EAMxB,YAAoB,MAAmB;AAAnB;AALpB,wBAAO;AACP,wBAAO;AACP,wBAAQ;AACR,wBAAQ;AAAA,EAEgC;AAAA,EAExC,IAAI,SAAS;AACX,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,QAAQ,QAAuB;AACnC,QAAI;AACF,WAAK,UAAU;AAGf,UAAI,KAAK,QAAQ,cAAc,QAAQ;AACrC,aAAK,SAAS,IAAI,2BAAW,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC3F,WAAW,KAAK,QAAQ,cAAc,QAAQ;AAC5C,aAAK,SAAS,IAAI,2BAAW,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC3F,WAAW,KAAK,QAAQ,cAAc,WAAW;AAC/C,aAAK,SAAS,IAAI,mCAAc,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC9F;AAKA,WAAK,oBAAoB,IAAI;AAAA,QAC3B,IAAI,8BAAU;AAAA,UACZ,eAAe,CAAE,KAAK,QAAQ,OAAe,IAAI;AAAA,UACjD,WAAW,KAAK,QAAQ;AAAA,QAC1B,CAAC;AAAA,MACH;AAEA,YAAM,mBAAmB,oBAAI,IAAc;AAC3C,WAAK,QAAQ,kBAAkB,QAAQ,CAAC,GAAG,MAAM;AAC/C,yBAAiB,IAAI,GAAG,CAAC;AAAA,MAC3B,CAAC;AACD,UAAI,KAAK,OAAQ,kBAAiB,IAAI,wBAAQ,KAAK,MAAM;AACzD,WAAK,kBAAkB,IAAI,gBAAgB;AAE3C,UAAI,KAAK,QAAQ,iBAAiB;AAChC,cAAM,KAAK,QAAQ,gBAAgB,KAAK,mBAAmB,KAAK,IAAkC;AAAA,MACpG;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,MAAM,iCAAiC,GAAG,KAAK,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,aAAa;AACX,SAAK,oBAAoB,YAAY;AAAA,EACvC;AACF;",
4
+ "sourcesContent": ["import { SimpleApplication } from '@dooboostore/simple-boot';\nimport { HashRouter, PathRouter, Router, RouterEventType } from '@dooboostore/core-web';\nimport { ElementRouter } from './router/ElementRouter';\nimport { SimOption } from '@dooboostore/simple-boot';\nimport { ConstructorType, OptionalType, Subscription } from '@dooboostore/core';\nimport { SwcAppInterface } from './types';\nimport { SimConfig } from '@dooboostore/simple-boot';\n\nexport type SwcConfigType = {\n routeType: 'path' | 'hash' | 'element';\n // connectMode?: 'direct' | 'swap' | 'clear-swap'; // hydrate \uC544\uC9C1 \uAC1C\uBC1C\uC911\n container?: symbol;\n otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | symbol, any>;\n path?: string;\n window: Window;\n onEngineStarted?: (sp: SimpleApplication, app: SwcAppInterface) => Promise<void> | void;\n onConnectedChildAfter?: (swcEl: HTMLElement) => void;\n onConnectedChildBefore?: (swcEl: HTMLElement) => void;\n onDisconnectedChildAfter?: (swcEl: HTMLElement) => void;\n onDisconnectedChildBefore?: (swcEl: HTMLElement) => void;\n onConnected?: (app: SwcAppInterface) => void;\n onDisconnected?: (app: SwcAppInterface) => void;\n ssr?: boolean;\n onStartedLazyDefineComponent?: ((w: Window)=> Promise<CustomElementConstructor> | void | string | any | CustomElementConstructor)[];\n\n onChildrenConnectedDone?: (app: SwcAppInterface) => void;\n // onChildrenSwcAppStartedDone?: (app: SwcAppInterface) => void;\n // childrenSwcAppStartedDoneCheckIntervalTime?: number;\n onChildrenRouteChanged?: (event: RouterEventType, app: SwcAppInterface) => void;\n childrenRouteChangedCheckIntervalTime?: number; // \uC790\uC2DD \uC5F0\uACB0 \uC644\uB8CC \uC774\uBCA4\uD2B8 \uB514\uBC14\uC6B4\uC2A4 \uD0C0\uC784 (ms)\n childrenConnectedDoneCheckIntervalTime?: number;\n};\n\nexport type SwcAttributeConfigType = OptionalType<SwcConfigType, 'routeType' | 'window'>;\n\nexport class SwcAppEngine {\n public simpleApplication?: SimpleApplication;\n public router?: Router;\n private routerSubscription?: Subscription;\n private _config?: SwcConfigType;\n\n constructor(private host: HTMLElement) {}\n\n get config() {\n return this._config;\n }\n\n async connect(config: SwcConfigType) {\n try {\n this._config = config;\n\n // Router Selection\n if (this._config.routeType === 'path') {\n this.router = new PathRouter({ window: this._config.window, firstUrl: this._config.path });\n } else if (this._config.routeType === 'hash') {\n this.router = new HashRouter({ window: this._config.window, firstUrl: this._config.path });\n } else if (this._config.routeType === 'element') {\n this.router = new ElementRouter({ window: this._config.window, firstUrl: this._config.path });\n }\n\n // console.log('vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv', this.router)\n\n // App start\n this.simpleApplication = new SimpleApplication(\n new SimOption({\n excludeProxys: [(this._config.window as any).Node],\n container: this._config.container\n })\n );\n\n const otherInstanceSim = new Map<any, any>();\n this.config?.otherInstanceSim?.forEach((v, k) => {\n otherInstanceSim.set(k, v);\n });\n if (this.router) otherInstanceSim.set(Router, this.router);\n this.simpleApplication.run(otherInstanceSim);\n\n\n if (this._config.onStartedLazyDefineComponent) {\n await Promise.all(this._config.onStartedLazyDefineComponent.map(it => it(this._config.window)))\n }\n if (this._config.onEngineStarted) {\n await this._config.onEngineStarted(this.simpleApplication, this.host as unknown as SwcAppInterface);\n }\n } catch (e) {\n console.error('[SWC-APP-ENGINE] Init failed:', e, this._config);\n }\n }\n\n disconnect() {\n this.routerSubscription?.unsubscribe();\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,sBAAgE;AAChE,2BAA8B;AAC9B,IAAAA,sBAA0B;AAgCnB,MAAM,aAAa;AAAA,EAMxB,YAAoB,MAAmB;AAAnB;AALpB,wBAAO;AACP,wBAAO;AACP,wBAAQ;AACR,wBAAQ;AAAA,EAEgC;AAAA,EAExC,IAAI,SAAS;AACX,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,QAAQ,QAAuB;AACnC,QAAI;AACF,WAAK,UAAU;AAGf,UAAI,KAAK,QAAQ,cAAc,QAAQ;AACrC,aAAK,SAAS,IAAI,2BAAW,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC3F,WAAW,KAAK,QAAQ,cAAc,QAAQ;AAC5C,aAAK,SAAS,IAAI,2BAAW,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC3F,WAAW,KAAK,QAAQ,cAAc,WAAW;AAC/C,aAAK,SAAS,IAAI,mCAAc,EAAE,QAAQ,KAAK,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,MAC9F;AAKA,WAAK,oBAAoB,IAAI;AAAA,QAC3B,IAAI,8BAAU;AAAA,UACZ,eAAe,CAAE,KAAK,QAAQ,OAAe,IAAI;AAAA,UACjD,WAAW,KAAK,QAAQ;AAAA,QAC1B,CAAC;AAAA,MACH;AAEA,YAAM,mBAAmB,oBAAI,IAAc;AAC3C,WAAK,QAAQ,kBAAkB,QAAQ,CAAC,GAAG,MAAM;AAC/C,yBAAiB,IAAI,GAAG,CAAC;AAAA,MAC3B,CAAC;AACD,UAAI,KAAK,OAAQ,kBAAiB,IAAI,wBAAQ,KAAK,MAAM;AACzD,WAAK,kBAAkB,IAAI,gBAAgB;AAG3C,UAAI,KAAK,QAAQ,8BAA8B;AAC7C,cAAM,QAAQ,IAAI,KAAK,QAAQ,6BAA6B,IAAI,QAAM,GAAG,KAAK,QAAQ,MAAM,CAAC,CAAC;AAAA,MAChG;AACA,UAAI,KAAK,QAAQ,iBAAiB;AAChC,cAAM,KAAK,QAAQ,gBAAgB,KAAK,mBAAmB,KAAK,IAAkC;AAAA,MACpG;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,MAAM,iCAAiC,GAAG,KAAK,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,aAAa;AACX,SAAK,oBAAoB,YAAY;AAAA,EACvC;AACF;",
6
6
  "names": ["import_simple_boot"]
7
7
  }
@@ -20,6 +20,10 @@ __export(addEventListener_exports, {
20
20
  ADD_EVENT_LISTENER_METADATA_KEY: () => ADD_EVENT_LISTENER_METADATA_KEY,
21
21
  addEventListener: () => addEventListener,
22
22
  addEventListenerAppHost: () => addEventListenerAppHost,
23
+ addEventListenerDelegate: () => addEventListenerDelegate,
24
+ addEventListenerDelegateAllDom: () => addEventListenerDelegateAllDom,
25
+ addEventListenerDelegateLightDom: () => addEventListenerDelegateLightDom,
26
+ addEventListenerDelegateShadowDom: () => addEventListenerDelegateShadowDom,
23
27
  addEventListenerDocument: () => addEventListenerDocument,
24
28
  addEventListenerThis: () => addEventListenerThis,
25
29
  addEventListenerWindow: () => addEventListenerWindow,
@@ -39,10 +43,18 @@ function addEventListener(selectorOrTarget, type, options = {}) {
39
43
  listeners.push({ propertyKey, selector: selectorOrTarget, type, options });
40
44
  };
41
45
  }
42
- const getAddEventListenerMetadata = (target) => {
43
- const constructor = target instanceof Function ? target : target.constructor;
44
- return import_core.ReflectUtils.getMetadata(ADD_EVENT_LISTENER_METADATA_KEY, constructor);
45
- };
46
+ function addEventListenerDelegateLightDom(selector, type, options) {
47
+ return addEventListener(selector, type, { ...options ?? {}, root: "light", delegate: true });
48
+ }
49
+ function addEventListenerDelegateShadowDom(selector, type, options) {
50
+ return addEventListener(selector, type, { ...options ?? {}, root: "shadow", delegate: true });
51
+ }
52
+ function addEventListenerDelegateAllDom(selector, type, options) {
53
+ return addEventListener(selector, type, { ...options ?? {}, root: "all", delegate: true });
54
+ }
55
+ function addEventListenerDelegate(selector, type, options) {
56
+ return addEventListener(selector, type, { ...options ?? {}, root: "auto", delegate: true });
57
+ }
46
58
  function addEventListenerThis(type, options) {
47
59
  return addEventListener("$this", type, options);
48
60
  }
@@ -55,4 +67,8 @@ function addEventListenerWindow(type, options) {
55
67
  function addEventListenerDocument(type, options) {
56
68
  return addEventListener("$document", type, options);
57
69
  }
70
+ const getAddEventListenerMetadata = (target) => {
71
+ const constructor = target instanceof Function ? target : target.constructor;
72
+ return import_core.ReflectUtils.getMetadata(ADD_EVENT_LISTENER_METADATA_KEY, constructor);
73
+ };
58
74
  //# sourceMappingURL=addEventListener.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/decorators/addEventListener.ts"],
4
- "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core';\nimport { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';\n\nexport interface AddEventListenerBaseOptions extends EventListenerOptions {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n stopPropagation?: boolean;\n stopImmediatePropagation?: boolean;\n preventDefault?: boolean;\n removeOnDisconnected?: boolean;\n delegate?: boolean;\n filter?: (target: Event | CustomEvent, meta:{currentThis: any, helper: HelperHostSet}) => boolean;\n}\n\nexport interface AddEventListenerMetadata {\n propertyKey: string | symbol;\n selector: string;\n type: string;\n options: AddEventListenerBaseOptions & SwcQueryOptions & { delegate?: boolean };\n}\n\nexport const ADD_EVENT_LISTENER_METADATA_KEY = Symbol.for('simple-web-component:add-event-listener');\n\nexport function addEventListener(target: SpecialSelector, type: string, options?: AddEventListenerBaseOptions): MethodDecorator;\nexport function addEventListener(selector: string, type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions & { delegate?: boolean }): MethodDecorator;\n/**\n * @addEventListener decorator to bind events to elements.\n */\nexport function addEventListener(selectorOrTarget: string, type: string, options: any = {}): MethodDecorator {\n return (targetObj: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const constructor = targetObj.constructor;\n\n let listeners = ReflectUtils.getMetadata<AddEventListenerMetadata[]>(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n if (!listeners) {\n listeners = [];\n ReflectUtils.defineMetadata(ADD_EVENT_LISTENER_METADATA_KEY, listeners, constructor);\n }\n\n listeners.push({ propertyKey, selector: selectorOrTarget, type, options });\n };\n}\n\nexport const getAddEventListenerMetadata = (target: any): AddEventListenerMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getMetadata(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n};\n\n/**\n * @addEventListenerThis decorator - simplified version of @addEventListener for $this selector\n */\nexport function addEventListenerThis(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$this', type, options);\n}\n\n/**\n * @addEventListenerAppHost decorator - simplified version of @addEventListener for $appHost selector\n */\nexport function addEventListenerAppHost(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$appHost', type, options);\n}\nexport function addEventListenerWindow(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$window', type, options);\n}\nexport function addEventListenerDocument(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$document', type, options);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6B;AAsBtB,MAAM,kCAAkC,OAAO,IAAI,yCAAyC;AAO5F,SAAS,iBAAiB,kBAA0B,MAAc,UAAe,CAAC,GAAoB;AAC3G,SAAO,CAAC,WAAmB,aAA8B,eAAmC;AAC1F,UAAM,cAAc,UAAU;AAE9B,QAAI,YAAY,yBAAa,YAAwC,iCAAiC,WAAW;AACjH,QAAI,CAAC,WAAW;AACd,kBAAY,CAAC;AACb,+BAAa,eAAe,iCAAiC,WAAW,WAAW;AAAA,IACrF;AAEA,cAAU,KAAK,EAAE,aAAa,UAAU,kBAAkB,MAAM,QAAQ,CAAC;AAAA,EAC3E;AACF;AAEO,MAAM,8BAA8B,CAAC,WAAwD;AAClG,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,yBAAa,YAAY,iCAAiC,WAAW;AAC9E;AAKO,SAAS,qBAAqB,MAAc,SAA0E;AAC3H,SAAO,iBAAiB,SAAS,MAAM,OAAO;AAChD;AAKO,SAAS,wBAAwB,MAAc,SAA0E;AAC9H,SAAO,iBAAiB,YAAY,MAAM,OAAO;AACnD;AACO,SAAS,uBAAuB,MAAc,SAA0E;AAC7H,SAAO,iBAAiB,WAAW,MAAM,OAAO;AAClD;AACO,SAAS,yBAAyB,MAAc,SAA0E;AAC/H,SAAO,iBAAiB,aAAa,MAAM,OAAO;AACpD;",
4
+ "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core';\nimport { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';\n\nexport interface AddEventListenerBaseOptions extends EventListenerOptions {\n capture?: boolean;\n once?: boolean;\n passive?: boolean;\n stopPropagation?: boolean;\n stopImmediatePropagation?: boolean;\n preventDefault?: boolean;\n // removeOnDisconnected?: boolean;\n delegate?: boolean;\n filter?: (target: Event | CustomEvent, meta:{currentThis: any, helper: HelperHostSet}) => boolean;\n}\n\nexport interface AddEventListenerMetadata {\n propertyKey: string | symbol;\n selector: string;\n type: string;\n options: AddEventListenerBaseOptions & SwcQueryOptions & { delegate?: boolean };\n}\n\nexport const ADD_EVENT_LISTENER_METADATA_KEY = Symbol.for('simple-web-component:add-event-listener');\n\nexport function addEventListener(target: SpecialSelector, type: string, options?: AddEventListenerBaseOptions): MethodDecorator;\nexport function addEventListener(selector: string, type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions & { delegate?: boolean }): MethodDecorator;\n/**\n * @addEventListener decorator to bind events to elements.\n */\nexport function addEventListener(selectorOrTarget: string, type: string, options: any = {}): MethodDecorator {\n return (targetObj: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n const constructor = targetObj.constructor;\n\n let listeners = ReflectUtils.getMetadata<AddEventListenerMetadata[]>(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n if (!listeners) {\n listeners = [];\n ReflectUtils.defineMetadata(ADD_EVENT_LISTENER_METADATA_KEY, listeners, constructor);\n }\n\n listeners.push({ propertyKey, selector: selectorOrTarget, type, options });\n };\n}\n\n\nexport function addEventListenerDelegateLightDom(selector: string, type: string, options?: Omit<AddEventListenerBaseOptions, 'delegate'>): MethodDecorator {\n return addEventListener(selector, type, {...options??{}, root:'light', delegate: true});\n}\n\nexport function addEventListenerDelegateShadowDom(selector: string, type: string, options?: Omit<AddEventListenerBaseOptions, 'delegate'>): MethodDecorator {\n return addEventListener(selector, type, {...options??{}, root:'shadow', delegate: true});\n}\nexport function addEventListenerDelegateAllDom(selector: string, type: string, options?: Omit<AddEventListenerBaseOptions, 'delegate'>): MethodDecorator {\n return addEventListener(selector, type, {...options??{}, root:'all', delegate: true});\n}\nexport function addEventListenerDelegate(selector: string, type: string, options?: Omit<AddEventListenerBaseOptions, 'delegate'>): MethodDecorator {\n return addEventListener(selector, type, {...options??{}, root:'auto', delegate: true});\n}\n\n/**\n * @addEventListenerThis decorator - simplified version of @addEventListener for $this selector\n */\nexport function addEventListenerThis(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$this', type, options);\n}\n\n/**\n * @addEventListenerAppHost decorator - simplified version of @addEventListener for $appHost selector\n */\nexport function addEventListenerAppHost(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$appHost', type, options);\n}\n\nexport function addEventListenerWindow(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$window', type, options);\n}\nexport function addEventListenerDocument(type: string, options?: AddEventListenerBaseOptions & SwcQueryOptions): MethodDecorator {\n return addEventListener('$document', type, options);\n}\n\nexport const getAddEventListenerMetadata = (target: any): AddEventListenerMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getMetadata(ADD_EVENT_LISTENER_METADATA_KEY, constructor);\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6B;AAsBtB,MAAM,kCAAkC,OAAO,IAAI,yCAAyC;AAO5F,SAAS,iBAAiB,kBAA0B,MAAc,UAAe,CAAC,GAAoB;AAC3G,SAAO,CAAC,WAAmB,aAA8B,eAAmC;AAC1F,UAAM,cAAc,UAAU;AAE9B,QAAI,YAAY,yBAAa,YAAwC,iCAAiC,WAAW;AACjH,QAAI,CAAC,WAAW;AACd,kBAAY,CAAC;AACb,+BAAa,eAAe,iCAAiC,WAAW,WAAW;AAAA,IACrF;AAEA,cAAU,KAAK,EAAE,aAAa,UAAU,kBAAkB,MAAM,QAAQ,CAAC;AAAA,EAC3E;AACF;AAGO,SAAS,iCAAiC,UAAkB,MAAc,SAA0E;AACzJ,SAAO,iBAAiB,UAAU,MAAM,EAAC,GAAG,WAAS,CAAC,GAAG,MAAK,SAAS,UAAU,KAAI,CAAC;AACxF;AAEO,SAAS,kCAAkC,UAAkB,MAAc,SAA0E;AAC1J,SAAO,iBAAiB,UAAU,MAAM,EAAC,GAAG,WAAS,CAAC,GAAG,MAAK,UAAU,UAAU,KAAI,CAAC;AACzF;AACO,SAAS,+BAA+B,UAAkB,MAAc,SAA0E;AACvJ,SAAO,iBAAiB,UAAU,MAAM,EAAC,GAAG,WAAS,CAAC,GAAG,MAAK,OAAO,UAAU,KAAI,CAAC;AACtF;AACO,SAAS,yBAAyB,UAAkB,MAAc,SAA0E;AACjJ,SAAO,iBAAiB,UAAU,MAAM,EAAC,GAAG,WAAS,CAAC,GAAG,MAAK,QAAQ,UAAU,KAAI,CAAC;AACvF;AAKO,SAAS,qBAAqB,MAAc,SAA0E;AAC3H,SAAO,iBAAiB,SAAS,MAAM,OAAO;AAChD;AAKO,SAAS,wBAAwB,MAAc,SAA0E;AAC9H,SAAO,iBAAiB,YAAY,MAAM,OAAO;AACnD;AAEO,SAAS,uBAAuB,MAAc,SAA0E;AAC7H,SAAO,iBAAiB,WAAW,MAAM,OAAO;AAClD;AACO,SAAS,yBAAyB,MAAc,SAA0E;AAC/H,SAAO,iBAAiB,aAAa,MAAM,OAAO;AACpD;AAEO,MAAM,8BAA8B,CAAC,WAAwD;AAClG,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,yBAAa,YAAY,iCAAiC,WAAW;AAC9E;",
6
6
  "names": []
7
7
  }