@dooboostore/simple-web-component 1.0.49 → 1.0.51

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 (251) hide show
  1. package/README.md +790 -337
  2. package/dist/cjs/SwcAppEngine.js.map +2 -2
  3. package/dist/cjs/decorators/addEventListener.js +1925 -22
  4. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  5. package/dist/cjs/decorators/applyAttribute.js +41 -47
  6. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  7. package/dist/cjs/decorators/applyClass.js +14 -11
  8. package/dist/cjs/decorators/applyClass.js.map +2 -2
  9. package/dist/cjs/decorators/applyNode.js +19 -21
  10. package/dist/cjs/decorators/applyNode.js.map +2 -2
  11. package/dist/cjs/decorators/applyProperty.js +24 -48
  12. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  13. package/dist/cjs/decorators/applySlot.js +9 -8
  14. package/dist/cjs/decorators/applySlot.js.map +2 -2
  15. package/dist/cjs/decorators/applyStyle.js +14 -11
  16. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  17. package/dist/cjs/decorators/around.js +124 -0
  18. package/dist/cjs/decorators/around.js.map +7 -0
  19. package/dist/cjs/decorators/changedAttribute.js +61 -24
  20. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  21. package/dist/cjs/decorators/elementDefine.js +240 -196
  22. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  23. package/dist/cjs/decorators/emitCustomEvent.js +14 -12
  24. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  25. package/dist/cjs/decorators/eventMedia.js +112 -0
  26. package/dist/cjs/decorators/eventMedia.js.map +7 -0
  27. package/dist/cjs/decorators/fetch.js +278 -0
  28. package/dist/cjs/decorators/fetch.js.map +7 -0
  29. package/dist/cjs/decorators/index.js +8 -2
  30. package/dist/cjs/decorators/index.js.map +2 -2
  31. package/dist/cjs/decorators/intersectionObserver.js +76 -65
  32. package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
  33. package/dist/cjs/decorators/lifecycles.js +11 -11
  34. package/dist/cjs/decorators/lifecycles.js.map +2 -2
  35. package/dist/cjs/decorators/mutationObserver.js +97 -90
  36. package/dist/cjs/decorators/mutationObserver.js.map +3 -3
  37. package/dist/cjs/decorators/parameter.js +156 -0
  38. package/dist/cjs/decorators/parameter.js.map +7 -0
  39. package/dist/cjs/decorators/publishSwcAppMessage.js +2 -2
  40. package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
  41. package/dist/cjs/decorators/query.js +11 -5
  42. package/dist/cjs/decorators/query.js.map +2 -2
  43. package/dist/cjs/decorators/requestAnimationFrame.js +115 -0
  44. package/dist/cjs/decorators/requestAnimationFrame.js.map +7 -0
  45. package/dist/cjs/decorators/resizeObserver.js +84 -69
  46. package/dist/cjs/decorators/resizeObserver.js.map +3 -3
  47. package/dist/cjs/decorators/setInterval.js +65 -22
  48. package/dist/cjs/decorators/setInterval.js.map +2 -2
  49. package/dist/cjs/decorators/setTimeout.js +68 -22
  50. package/dist/cjs/decorators/setTimeout.js.map +2 -2
  51. package/dist/cjs/decorators/state.js +13 -10
  52. package/dist/cjs/decorators/state.js.map +2 -2
  53. package/dist/cjs/decorators/{subscribeSwcAppMessageWhileConnected.js → subscribeSwcAppMessage.js} +20 -21
  54. package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +7 -0
  55. package/dist/cjs/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +23 -19
  56. package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +7 -0
  57. package/dist/cjs/decorators/swcAppRoute.js +149 -0
  58. package/dist/cjs/decorators/swcAppRoute.js.map +7 -0
  59. package/dist/cjs/elements/SwcApp.js +70 -0
  60. package/dist/cjs/elements/SwcApp.js.map +2 -2
  61. package/dist/cjs/elements/SwcAppMixin.js +256 -67
  62. package/dist/cjs/elements/SwcAppMixin.js.map +3 -3
  63. package/dist/cjs/types/index.js +5 -1
  64. package/dist/cjs/types/index.js.map +2 -2
  65. package/dist/cjs/types/window.d.js.map +1 -1
  66. package/dist/cjs/utils/Utils.js +36 -15
  67. package/dist/cjs/utils/Utils.js.map +2 -2
  68. package/dist/esm/SwcAppEngine.js.map +2 -2
  69. package/dist/esm/decorators/addEventListener.js +1925 -22
  70. package/dist/esm/decorators/addEventListener.js.map +2 -2
  71. package/dist/esm/decorators/applyAttribute.js +41 -47
  72. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  73. package/dist/esm/decorators/applyClass.js +14 -11
  74. package/dist/esm/decorators/applyClass.js.map +2 -2
  75. package/dist/esm/decorators/applyNode.js +20 -22
  76. package/dist/esm/decorators/applyNode.js.map +2 -2
  77. package/dist/esm/decorators/applyProperty.js +24 -48
  78. package/dist/esm/decorators/applyProperty.js.map +2 -2
  79. package/dist/esm/decorators/applySlot.js +9 -8
  80. package/dist/esm/decorators/applySlot.js.map +2 -2
  81. package/dist/esm/decorators/applyStyle.js +14 -11
  82. package/dist/esm/decorators/applyStyle.js.map +2 -2
  83. package/dist/esm/decorators/around.js +105 -0
  84. package/dist/esm/decorators/around.js.map +7 -0
  85. package/dist/esm/decorators/changedAttribute.js +61 -24
  86. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  87. package/dist/esm/decorators/elementDefine.js +238 -194
  88. package/dist/esm/decorators/elementDefine.js.map +3 -3
  89. package/dist/esm/decorators/emitCustomEvent.js +15 -13
  90. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  91. package/dist/esm/decorators/eventMedia.js +94 -0
  92. package/dist/esm/decorators/eventMedia.js.map +7 -0
  93. package/dist/esm/decorators/fetch.js +259 -0
  94. package/dist/esm/decorators/fetch.js.map +7 -0
  95. package/dist/esm/decorators/index.js +8 -2
  96. package/dist/esm/decorators/index.js.map +2 -2
  97. package/dist/esm/decorators/intersectionObserver.js +76 -65
  98. package/dist/esm/decorators/intersectionObserver.js.map +2 -2
  99. package/dist/esm/decorators/lifecycles.js +11 -11
  100. package/dist/esm/decorators/lifecycles.js.map +2 -2
  101. package/dist/esm/decorators/mutationObserver.js +97 -90
  102. package/dist/esm/decorators/mutationObserver.js.map +3 -3
  103. package/dist/esm/decorators/parameter.js +137 -0
  104. package/dist/esm/decorators/parameter.js.map +7 -0
  105. package/dist/esm/decorators/publishSwcAppMessage.js +2 -2
  106. package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
  107. package/dist/esm/decorators/query.js +11 -5
  108. package/dist/esm/decorators/query.js.map +2 -2
  109. package/dist/esm/decorators/requestAnimationFrame.js +96 -0
  110. package/dist/esm/decorators/requestAnimationFrame.js.map +7 -0
  111. package/dist/esm/decorators/resizeObserver.js +84 -69
  112. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  113. package/dist/esm/decorators/setInterval.js +65 -23
  114. package/dist/esm/decorators/setInterval.js.map +2 -2
  115. package/dist/esm/decorators/setTimeout.js +68 -23
  116. package/dist/esm/decorators/setTimeout.js.map +2 -2
  117. package/dist/esm/decorators/state.js +13 -10
  118. package/dist/esm/decorators/state.js.map +2 -2
  119. package/dist/esm/decorators/subscribeSwcAppMessage.js +53 -0
  120. package/dist/esm/decorators/subscribeSwcAppMessage.js.map +7 -0
  121. package/dist/esm/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +20 -16
  122. package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +7 -0
  123. package/dist/esm/decorators/swcAppRoute.js +130 -0
  124. package/dist/esm/decorators/swcAppRoute.js.map +7 -0
  125. package/dist/esm/elements/SwcApp.js +70 -0
  126. package/dist/esm/elements/SwcApp.js.map +2 -2
  127. package/dist/esm/elements/SwcAppMixin.js +258 -69
  128. package/dist/esm/elements/SwcAppMixin.js.map +3 -3
  129. package/dist/esm/types/index.js +5 -1
  130. package/dist/esm/types/index.js.map +2 -2
  131. package/dist/esm/utils/Utils.js +36 -15
  132. package/dist/esm/utils/Utils.js.map +2 -2
  133. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +4395 -1266
  134. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  135. package/dist/types/SwcAppEngine.d.ts +1 -0
  136. package/dist/types/SwcAppEngine.d.ts.map +1 -1
  137. package/dist/types/decorators/addEventListener.d.ts +936 -11
  138. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  139. package/dist/types/decorators/applyAttribute.d.ts +27 -37
  140. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  141. package/dist/types/decorators/applyClass.d.ts +2 -2
  142. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  143. package/dist/types/decorators/applyNode.d.ts +16 -16
  144. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  145. package/dist/types/decorators/applyProperty.d.ts +28 -44
  146. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  147. package/dist/types/decorators/applySlot.d.ts.map +1 -1
  148. package/dist/types/decorators/applyStyle.d.ts +2 -2
  149. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  150. package/dist/types/decorators/around.d.ts +87 -0
  151. package/dist/types/decorators/around.d.ts.map +1 -0
  152. package/dist/types/decorators/changedAttribute.d.ts +22 -4
  153. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  154. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  155. package/dist/types/decorators/emitCustomEvent.d.ts +0 -1
  156. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  157. package/dist/types/decorators/eventMedia.d.ts +48 -0
  158. package/dist/types/decorators/eventMedia.d.ts.map +1 -0
  159. package/dist/types/decorators/fetch.d.ts +139 -0
  160. package/dist/types/decorators/fetch.d.ts.map +1 -0
  161. package/dist/types/decorators/index.d.ts +8 -2
  162. package/dist/types/decorators/index.d.ts.map +1 -1
  163. package/dist/types/decorators/intersectionObserver.d.ts +32 -10
  164. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
  165. package/dist/types/decorators/lifecycles.d.ts +8 -7
  166. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  167. package/dist/types/decorators/mutationObserver.d.ts +34 -12
  168. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  169. package/dist/types/decorators/parameter.d.ts +113 -0
  170. package/dist/types/decorators/parameter.d.ts.map +1 -0
  171. package/dist/types/decorators/publishSwcAppMessage.d.ts +0 -1
  172. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
  173. package/dist/types/decorators/query.d.ts +7 -7
  174. package/dist/types/decorators/query.d.ts.map +1 -1
  175. package/dist/types/decorators/requestAnimationFrame.d.ts +47 -0
  176. package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -0
  177. package/dist/types/decorators/resizeObserver.d.ts +34 -12
  178. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  179. package/dist/types/decorators/setInterval.d.ts +27 -5
  180. package/dist/types/decorators/setInterval.d.ts.map +1 -1
  181. package/dist/types/decorators/setTimeout.d.ts +27 -5
  182. package/dist/types/decorators/setTimeout.d.ts.map +1 -1
  183. package/dist/types/decorators/state.d.ts.map +1 -1
  184. package/dist/types/decorators/subscribeSwcAppMessage.d.ts +44 -0
  185. package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -0
  186. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +60 -0
  187. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +1 -0
  188. package/dist/types/decorators/swcAppRoute.d.ts +94 -0
  189. package/dist/types/decorators/swcAppRoute.d.ts.map +1 -0
  190. package/dist/types/elements/SwcApp.d.ts.map +1 -1
  191. package/dist/types/elements/SwcAppMixin.d.ts +423 -388
  192. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  193. package/dist/types/types/index.d.ts +43 -4
  194. package/dist/types/types/index.d.ts.map +1 -1
  195. package/dist/types/utils/Utils.d.ts +15 -5
  196. package/dist/types/utils/Utils.d.ts.map +1 -1
  197. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +4395 -1266
  198. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  199. package/package.json +8 -6
  200. package/src/SwcAppEngine.ts +1 -0
  201. package/src/decorators/addEventListener.ts +1086 -28
  202. package/src/decorators/applyAttribute.ts +82 -134
  203. package/src/decorators/applyClass.ts +14 -10
  204. package/src/decorators/applyNode.ts +39 -37
  205. package/src/decorators/applyProperty.ts +72 -100
  206. package/src/decorators/applySlot.ts +9 -8
  207. package/src/decorators/applyStyle.ts +14 -10
  208. package/src/decorators/around.ts +196 -0
  209. package/src/decorators/changedAttribute.ts +65 -26
  210. package/src/decorators/elementDefine.ts +298 -220
  211. package/src/decorators/emitCustomEvent.ts +17 -13
  212. package/src/decorators/eventMedia.ts +119 -0
  213. package/src/decorators/fetch.ts +454 -0
  214. package/src/decorators/index.ts +8 -2
  215. package/src/decorators/intersectionObserver.ts +108 -78
  216. package/src/decorators/lifecycles.ts +24 -22
  217. package/src/decorators/mutationObserver.ts +140 -104
  218. package/src/decorators/parameter.ts +212 -0
  219. package/src/decorators/publishSwcAppMessage.ts +3 -4
  220. package/src/decorators/query.ts +22 -14
  221. package/src/decorators/requestAnimationFrame.ts +149 -0
  222. package/src/decorators/resizeObserver.ts +119 -82
  223. package/src/decorators/setInterval.ts +90 -23
  224. package/src/decorators/setTimeout.ts +93 -23
  225. package/src/decorators/state.ts +19 -13
  226. package/src/decorators/subscribeSwcAppMessage.ts +106 -0
  227. package/src/decorators/subscribeSwcAppRouteChange.ts +131 -0
  228. package/src/decorators/swcAppRoute.ts +231 -0
  229. package/src/elements/SwcApp.ts +40 -10
  230. package/src/elements/SwcAppMixin.ts +329 -85
  231. package/src/types/index.ts +38 -5
  232. package/src/types/window.d.ts +2 -18
  233. package/src/utils/Utils.ts +50 -18
  234. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  235. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  236. package/dist/cjs/examples/RxJSOperatorsExample.js +0 -285
  237. package/dist/cjs/examples/RxJSOperatorsExample.js.map +0 -7
  238. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +0 -54
  239. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  240. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  241. package/dist/esm/examples/RxJSOperatorsExample.js +0 -266
  242. package/dist/esm/examples/RxJSOperatorsExample.js.map +0 -7
  243. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +0 -23
  244. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +0 -1
  245. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +0 -31
  246. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +0 -1
  247. package/dist/types/examples/RxJSOperatorsExample.d.ts +0 -94
  248. package/dist/types/examples/RxJSOperatorsExample.d.ts.map +0 -1
  249. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +0 -91
  250. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +0 -107
  251. package/src/examples/RxJSOperatorsExample.ts +0 -279
@@ -1,5 +1,6 @@
1
1
  import { SimpleApplication } from '@dooboostore/simple-boot';
2
2
  import { Router } from '@dooboostore/core-web';
3
+ import type { Observable } from '@dooboostore/core';
3
4
  import {SwcAttributeConfigType, SwcConfigType} from "../SwcAppEngine";
4
5
 
5
6
  export enum InjectSituationType {
@@ -55,10 +56,21 @@ export type SwcAppMessage<T = any> = {
55
56
  type?: string;
56
57
  };
57
58
 
59
+ /**
60
+ * 늦게 연결/구독한 쪽에 과거 메시지를 재생하는 방식 (@subscribeSwcAppMessage, observeMessage 공통).
61
+ * - 'subject' 또는 미지정: live만
62
+ * - 'behavior': 버퍼의 마지막 1개 먼저
63
+ * - 'replay': 버퍼 전체를 시간순으로 먼저
64
+ */
65
+ export type SwcAppMessageSubject = 'subject' | 'behavior' | 'replay';
66
+
67
+ /** observeMessage 옵션. type이 없으면 전 타입 live (타입별 버퍼라 재생은 type이 있을 때만). */
68
+ export type SwcAppMessageObserveOptions = { type?: string; subject?: SwcAppMessageSubject };
58
69
 
59
- export interface SwcAppInterface extends HTMLElement {
70
+
71
+ export interface SwcAppInterface extends HTMLElement, SwcElement {
60
72
  simpleApplication?: SimpleApplication;
61
- config?: SwcConfigType;
73
+ config?: SwcConfigType;
62
74
  router?: Router;
63
75
  connect(config?: SwcAttributeConfigType): Promise<void>;
64
76
  routing(path: string): Promise<void>;
@@ -66,10 +78,23 @@ export interface SwcAppInterface extends HTMLElement {
66
78
  back(): void;
67
79
  forward(): void;
68
80
  publishMessage(message: SwcAppMessage): void;
81
+ /** 코드로 메시지 구독 (RxJS 스타일). 반환된 Observable을 subscribe하고, 끝나면 unsubscribe. */
82
+ observeMessage<T = any>(): Observable<SwcAppMessage<T>>;
83
+ observeMessage<T = any>(type: string): Observable<SwcAppMessage<T>>;
84
+ observeMessage<T = any>(type: string, options: Omit<SwcAppMessageObserveOptions, 'type'>): Observable<SwcAppMessage<T>>;
85
+ observeMessage<T = any>(options: SwcAppMessageObserveOptions): Observable<SwcAppMessage<T>>;
86
+ /** 현재 연결된 자식 엘리먼트 목록 */
87
+ connectedElements(): Array<HTMLElement & SwcElement>;
69
88
  }
70
89
 
71
90
  export interface SwcElement {
72
- _swcId: string;
91
+ _swcId?: string;
92
+ __swc_initialized?: boolean;
93
+ __swc_proto_setup?: boolean;
94
+ __swc_observers?: (MutationObserver | ResizeObserver | IntersectionObserver)[];
95
+ _emitHandlers?: Map<any, any>;
96
+ __swc_attributeEventHandlers?: Map<any, any>;
97
+ // __swc_handled?: any;
73
98
  // createSlotString(id: string): string
74
99
  // createEaHtml(id: string, script: string): string
75
100
  // createEaText(id: string, script: string): string
@@ -170,7 +195,7 @@ export interface OnConnectedResult {
170
195
  * const cyclers: ElementDefineLifeCycler[] = [eventCycler, ...]; // elementDefine 시 1회 생성
171
196
  *
172
197
  * proto.connectedCallback = async function () {
173
- * const helperHostSet = SwcUtils.getHelperAndHostSet(win, this);
198
+ * const helperHostSet = SwcUtils.getHelperAndHostSet(this);
174
199
  * const results = await Promise.all(cyclers.map(c => c.onConnected?.(helperHostSet)));
175
200
  * // results 에서 mutationObserverSet / resizeObserverSet 수집
176
201
  * // → 필요한 경우에만 MutationObserver / ResizeObserver 생성
@@ -180,6 +205,13 @@ export interface OnConnectedResult {
180
205
  * };
181
206
  * ```
182
207
  */
208
+ // observer 메타 phase 분류: 자기 자신(bare/$this, non-delegate)은 렌더 전에, 나머지는 렌더 후에 붙는다.
209
+ export type ObserverScope = 'self' | 'rest';
210
+ export const isSelfObserverMeta = (m: { selector?: unknown; options?: { delegate?: boolean } }): boolean =>
211
+ !m.options?.delegate && (m.selector === '$this' || m.selector === '');
212
+ export const inObserverScope = (m: { selector?: unknown; options?: { delegate?: boolean } }, scope?: ObserverScope): boolean =>
213
+ !scope || (scope === 'self') === isSelfObserverMeta(m);
214
+
183
215
  export interface ElementDefineLifeCycler {
184
216
  /**
185
217
  * connectedCallback 시 호출.
@@ -187,8 +219,9 @@ export interface ElementDefineLifeCycler {
187
219
  * 필요 없으면 void / undefined 를 반환한다.
188
220
  * @param helperHostSet 현재 엘리먼트 인스턴스($this)를 포함한 컨텍스트
189
221
  * @param resizeObserverSet 이전 시클러가 반환한 resize observer set (mutation 시클러가 주입받아 사용)
222
+ * @param scope observer 시클러 전용 — 'self'(렌더 전, 자기 자신 메타만) / 'rest'(렌더 후, 나머지). 없으면 전부.
190
223
  */
191
- onConnected?(helperHostSet: HelperHostSet, resizeObserverSet?: ResizeObserverSet): OnConnectedResult | void | Promise<OnConnectedResult | void>;
224
+ onConnected?(helperHostSet: HelperHostSet, resizeObserverSet?: ResizeObserverSet, scope?: ObserverScope): OnConnectedResult | void | Promise<OnConnectedResult | void>;
192
225
 
193
226
  /** disconnectedCallback 시 호출. 등록한 리소스를 해제한다. */
194
227
  onDisconnected?(helperHostSet: HelperHostSet): void;
@@ -23,27 +23,11 @@ declare global {
23
23
  history: History;
24
24
  console: Console;
25
25
  IntersectionObserver: typeof IntersectionObserver;
26
+ ResizeObserver: typeof ResizeObserver;
27
+ MutationObserver: typeof MutationObserver;
26
28
  SwaggerUIBundle: any;
27
29
 
28
30
  }
29
-
30
- namespace Dooboostore {
31
- interface PackageInfo {
32
- id: string;
33
- name: string;
34
- description: string;
35
- longDescription: string;
36
- icon: string;
37
- color: string;
38
- features: PackageFeature[];
39
- example: string;
40
- }
41
-
42
- interface PackageFeature {
43
- title: string;
44
- desc: string;
45
- }
46
- }
47
31
  }
48
32
 
49
33
  export {};
@@ -213,7 +213,18 @@ export namespace SwcUtils {
213
213
  } as const;
214
214
  };
215
215
 
216
- export const getHelperAndHostSet = (win: Window, el: HTMLElement): HelperHostSet => {
216
+ /** el 의 window — 자기 elementDefine 설정 → 가까운 조상 SWC 호스트 설정 → 전역 window 순. */
217
+ export const resolveWindow = (el: HTMLElement | Node): Window => {
218
+ const hosts = findAllSwcHostsIncludingSelf(el);
219
+ for (let i = hosts.length - 1; i >= 0; i--) {
220
+ const w = getElementConfig(hosts[i])?.window;
221
+ if (w) return w;
222
+ }
223
+ return (typeof window !== 'undefined' ? window : undefined) as Window;
224
+ };
225
+
226
+ /** win 생략 시 resolveWindow(el). el 이 SWC 요소가 아니면(이벤트 target 등) 호스트의 window 를 넘긴다. */
227
+ export const getHelperAndHostSet = (el: HTMLElement, win: Window = resolveWindow(el)): HelperHostSet => {
217
228
  const helperSet = getHelperSet(win);
218
229
  const hostSet = getHostSet(el);
219
230
  return {
@@ -237,17 +248,19 @@ export namespace SwcUtils {
237
248
  };
238
249
 
239
250
  /**
240
- * Finds the nearest logical SWC host for an element.
241
- * Checks __swc_host property first, then climbs the DOM tree.
251
+ * Finds the nearest logical SWC host for an element (excluding self).
252
+ * Checks __swc_host property first, then climbs the DOM tree from the parent.
242
253
  */
243
- export const findNearestSwcHostIncludingSelf = (el: HTMLElement | Node): HTMLElement | undefined => {
254
+ export const findNearestSwcAncestorHost = (el: HTMLElement | Node): HTMLElement | undefined => {
244
255
  const el1 = el as any;
245
256
  if (el1.__swc_host) return el1.__swc_host;
246
257
 
247
258
  let current: any = el.parentElement || (el.getRootNode?.() as any)?.host;
248
259
  const doc = el.ownerDocument;
249
260
  const win = doc?.defaultView || ((typeof window !== 'undefined' ? window : undefined) as any);
261
+ let guard = 0;
250
262
  while (current && current !== doc && current !== win) {
263
+ if (++guard > 50) break;
251
264
  if (current.__swc_host) return current.__swc_host;
252
265
  if (getElementConfig(current)) return current as HTMLElement;
253
266
  current = current.parentElement || (current.getRootNode?.() as any)?.host;
@@ -256,28 +269,24 @@ export namespace SwcUtils {
256
269
  };
257
270
 
258
271
  /**
259
- * Returns all SWC ancestors (excluding self) in [root, ..., parent] order.
272
+ * Returns all SWC hosts in [root, ..., parent, self] order (self only when el is an SWC element).
260
273
  */
261
274
  export const findAllSwcHostsIncludingSelf = (el: HTMLElement | Node): HTMLElement[] => {
262
- const hosts: HTMLElement[] = [];
263
- let current = findNearestSwcHostIncludingSelf(el);
275
+ const hosts: HTMLElement[] = getElementConfig(el) ? [el as HTMLElement] : [];
276
+ let current = findNearestSwcAncestorHost(el);
264
277
  while (current) {
265
278
  hosts.push(current);
266
279
  // To find the next ancestor, we must start searching from the PARENT of the found host
267
- current = findNearestSwcHostIncludingSelf(current);
280
+ current = findNearestSwcAncestorHost(current);
268
281
  }
269
282
  return hosts.reverse();
270
283
  };
271
284
 
272
- export const getHosts = (el: HTMLElement): HTMLElement[] => {
273
- const ancestors = findAllSwcHostsIncludingSelf(el);
274
- if (getElementConfig(el)) return [...ancestors, el];
275
- return ancestors;
276
- };
285
+ export const getHosts = (el: HTMLElement): HTMLElement[] => findAllSwcHostsIncludingSelf(el);
277
286
 
278
287
  export const getHost = (el: HTMLElement): HTMLElement | undefined => {
279
288
  if (getElementConfig(el)) return el;
280
- return findNearestSwcHostIncludingSelf(el);
289
+ return findNearestSwcAncestorHost(el);
281
290
  };
282
291
 
283
292
 
@@ -305,7 +314,6 @@ export namespace SwcUtils {
305
314
  t = SwcUtils.processHtml(id, t, {
306
315
  document: document,
307
316
  replaceWrap: {start: /a::\w+=\s*"/, end: /"\s/}, replacer: (id, script, er) => {
308
- console.log('start: /a-->', er)
309
317
  const match = er.expressionStart.match(/^\w+::(\w+)="/)
310
318
  const name = match?.[1];
311
319
  return ElementApply.attribute(id, name, script)
@@ -317,7 +325,6 @@ export namespace SwcUtils {
317
325
  t = SwcUtils.processHtml(id, t, {
318
326
  document: document,
319
327
  replaceWrap: {start: /e::\w+=\s*"/, end: /"\s/}, replacer: (id, script, er) => {
320
- console.log('start: /e-->', er)
321
328
  const match = er.expressionStart.match(/^\w+::(\w+)="/)
322
329
  const name = match?.[1];
323
330
  return ElementApply.event(id, name, script)
@@ -330,7 +337,6 @@ export namespace SwcUtils {
330
337
  t = SwcUtils.processHtml(id, t, {
331
338
  document: document,
332
339
  replaceWrap: {start: /p:\w+=\s*"/, end: /"\s/}, replacer: (id, script, er) => {
333
- console.log('start: /p-->', er)
334
340
  const match = er.expressionStart.match(/^\w+:(\w+)="/)
335
341
  const name = match?.[1];
336
342
  return ElementApply.property(id, name, script)
@@ -497,6 +503,9 @@ export namespace SwcUtils {
497
503
  // el 자체부터 시작 (el이 app host일 수도 있음)
498
504
  let current: HTMLElement | null = el;
499
505
 
506
+ // NOTE: 이름으로만 찾는다. define 전에는 껍데기 엘리먼트라 메서드·instanceof로
507
+ // 판별 불가 (Safari 폴리필은 업그레이드 순서도 child-first). 'swc-app' 태그 또는
508
+ // is="swc-app-*" 속성이 유일한 단서. 커스텀 호스트도 반드시 이 prefix를 쓸 것.
500
509
  while (current) {
501
510
  const isAppHost =
502
511
  current.tagName.toLowerCase() === 'swc-app' ||
@@ -525,7 +534,8 @@ export namespace SwcUtils {
525
534
  };
526
535
 
527
536
  export const getHostSet = (el: HTMLElement): HostSet => {
528
- const ancestors = findAllSwcHostsIncludingSelf(el); // [root, ..., parent]
537
+ const hosts = findAllSwcHostsIncludingSelf(el);
538
+ const ancestors = hosts[hosts.length - 1] === el ? hosts.slice(0, -1) : hosts; // [root, ..., parent] — $host 는 자기 자신이 아닌 부모
529
539
 
530
540
  const $host = ancestors.length > 0 ? ancestors[ancestors.length - 1] : null;
531
541
  const $parentHost = ancestors.length > 1 ? ancestors[ancestors.length - 2] : null;
@@ -595,6 +605,28 @@ export namespace SwcUtils {
595
605
  return result;
596
606
  };
597
607
 
608
+ /**
609
+ * parsePathPattern 과 같은 매칭이지만, 같은 이름의 변수가 여러 번 나오면 모든 값을 순서대로 모은다.
610
+ * '/a/{id}/b/{id}' ← '/a/1/b/2' → { id: ['1', '2'] } (parsePathPattern 은 마지막 값 '2' 로 덮어씀)
611
+ */
612
+ export const parsePathPatternAll = (pattern: string | undefined, currentPath: string): { [key: string]: string[] } | null => {
613
+ if (pattern === null || pattern === undefined) return {};
614
+ const trimmedPattern = pattern.trim();
615
+ if (trimmedPattern === '' && pattern !== '') return {};
616
+ const paramNames: string[] = [];
617
+ const regexPattern = trimmedPattern.replace(/{(\w+)(?::(.+?))?}/g, (match, paramName, customRegex) => {
618
+ paramNames.push(paramName);
619
+ return `(${customRegex || '[^/]+'})`;
620
+ });
621
+ const match = currentPath.match(new RegExp(`^${regexPattern}$`));
622
+ if (!match) return null;
623
+ const result: { [key: string]: string[] } = {};
624
+ paramNames.forEach((name, index) => {
625
+ (result[name] ??= []).push(match[index + 1]);
626
+ });
627
+ return result;
628
+ };
629
+
598
630
 
599
631
  }
600
632
  ;
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/decorators/subscribeSwcAppMessageWhileConnected.ts"],
4
- "sourcesContent": ["import { ReflectUtils } from '@dooboostore/core';\nimport { SwcAppMessage, SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';\n\nexport const SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY = Symbol.for('simple-web-component:subscribe-swc-app-message-while-connected');\n\nexport interface SwcAppMessageSubscriberMetadata {\n propertyKey: string | symbol;\n messageType?: string;\n filter?: (message: SwcAppMessage, currentThis: any) => boolean;\n}\n\nexport interface SwcAppMessageOptions {\n filter?: (message: SwcAppMessage, currentThis: any) => boolean;\n}\n\nfunction createSubscribeSwcAppMessageWhileConnected(options?: SwcAppMessageOptions, messageType?: string): MethodDecorator {\n return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {\n const filter = options?.filter;\n\n const constructor = target.constructor;\n let list = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, constructor) as SwcAppMessageSubscriberMetadata[];\n if (!list) {\n list = [];\n ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, list, constructor);\n }\n list.push({ propertyKey, messageType, filter });\n \n return descriptor;\n };\n}\n\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uC9C1\uC811 \uC0AC\uC6A9 (\uAD04\uD638 \uC5C6\uC74C)\nexport function subscribeSwcAppMessageWhileConnected(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uD568\uC218 \uD638\uCD9C (\uAD04\uD638 \uC788\uC74C) - \uBA54\uC2DC\uC9C0 \uD0C0\uC785\uB9CC\nexport function subscribeSwcAppMessageWhileConnected(messageType: string): MethodDecorator;\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uD568\uC218 \uD638\uCD9C (\uAD04\uD638 \uC788\uC74C) - \uC635\uC158\uB9CC\nexport function subscribeSwcAppMessageWhileConnected(options: SwcAppMessageOptions): MethodDecorator;\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uD568\uC218 \uD638\uCD9C (\uAD04\uD638 \uC788\uC74C) - \uBA54\uC2DC\uC9C0 \uD0C0\uC785 + \uC635\uC158\nexport function subscribeSwcAppMessageWhileConnected(messageType: string, options: SwcAppMessageOptions): MethodDecorator;\n\nexport function subscribeSwcAppMessageWhileConnected(targetOrMessageTypeOrOptions?: any, optionsOrPropertyKey?: any, descriptor?: PropertyDescriptor): any {\n // \uC9C1\uC811 \uB370\uCF54\uB808\uC774\uD130\uB85C \uC0AC\uC6A9\uB41C \uACBD\uC6B0 (\uAD04\uD638 \uC5C6\uC74C): @subscribeSwcAppMessageWhileConnected\n if (targetOrMessageTypeOrOptions && typeof targetOrMessageTypeOrOptions === 'object' && \n optionsOrPropertyKey && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol') &&\n descriptor) {\n const target = targetOrMessageTypeOrOptions;\n const propertyKey = optionsOrPropertyKey;\n return createSubscribeSwcAppMessageWhileConnected({})(target, propertyKey, descriptor);\n }\n\n // \uD568\uC218\uB85C \uD638\uCD9C\uB41C \uACBD\uC6B0 (\uAD04\uD638 \uC788\uC74C)\n let messageType: string | undefined;\n let options: SwcAppMessageOptions = {};\n\n if (typeof targetOrMessageTypeOrOptions === 'string') {\n // \uBA54\uC2DC\uC9C0 \uD0C0\uC785 \uC804\uB2EC: @subscribeSwcAppMessageWhileConnected('messageType') \uB610\uB294 @subscribeSwcAppMessageWhileConnected('messageType', options)\n messageType = targetOrMessageTypeOrOptions;\n if (optionsOrPropertyKey && typeof optionsOrPropertyKey === 'object') {\n options = optionsOrPropertyKey;\n }\n } else if (targetOrMessageTypeOrOptions && typeof targetOrMessageTypeOrOptions === 'object') {\n // \uC635\uC158\uB9CC \uC804\uB2EC: @subscribeSwcAppMessageWhileConnected({ filter: ... })\n options = targetOrMessageTypeOrOptions;\n }\n\n return createSubscribeSwcAppMessageWhileConnected(options, messageType);\n}\n\nexport const receiveMessage = subscribeSwcAppMessageWhileConnected;\n// Helper function to retrieve message subscribers metadata\nexport const getSubscribeSwcAppMessageWhileConnectedMetadata = (target: any): SwcAppMessageSubscriberMetadata[] | undefined => {\n const constructor = target instanceof Function ? target : target.constructor;\n return ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, constructor);\n};\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// MessageSubscribeLifeCycler\n// NOTE: \uC2E4\uC81C \uAD6C\uB3C5 \uB85C\uC9C1\uC740 SwcAppMixin._connected \uC5D0\uC11C \uCC98\uB9AC\uB41C\uB2E4.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport { ElementDefineLifeCycler } from '../types';\n\nexport class MessageSubscribeLifeCycler implements ElementDefineLifeCycler {\n onConnected(_helperHostSet: HelperHostSet): void {\n // \uC2E4\uC81C \uAD6C\uB3C5\uC740 SwcAppMixin._connected \uC5D0\uC11C \uCC98\uB9AC\n }\n\n /** SwcAppMixin \uC774 \uAD6C\uB3C5 \uB300\uC0C1 \uBA54\uD0C0\uB97C \uAEBC\uB0BC \uB54C \uC0AC\uC6A9 */\n getMetadata(helperHostSet: HelperHostSet): SwcAppMessageSubscriberMetadata[] | undefined {\n return getSubscribeSwcAppMessageWhileConnectedMetadata(helperHostSet.$this);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6B;AAGtB,MAAM,yDAAyD,OAAO,IAAI,gEAAgE;AAYjJ,SAAS,2CAA2C,SAAgC,aAAuC;AACzH,SAAO,CAAC,QAAgB,aAA8B,eAAoC;AACxF,UAAM,SAAS,SAAS;AAExB,UAAM,cAAc,OAAO;AAC3B,QAAI,OAAO,yBAAa,eAAe,wDAAwD,WAAW;AAC1G,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AACR,+BAAa,eAAe,wDAAwD,MAAM,WAAW;AAAA,IACvG;AACA,SAAK,KAAK,EAAE,aAAa,aAAa,OAAO,CAAC;AAE9C,WAAO;AAAA,EACT;AACF;AAWO,SAAS,qCAAqC,8BAAoC,sBAA4B,YAAsC;AAEzJ,MAAI,gCAAgC,OAAO,iCAAiC,YACxE,yBAAyB,OAAO,yBAAyB,YAAY,OAAO,yBAAyB,aACrG,YAAY;AACd,UAAM,SAAS;AACf,UAAM,cAAc;AACpB,WAAO,2CAA2C,CAAC,CAAC,EAAE,QAAQ,aAAa,UAAU;AAAA,EACvF;AAGA,MAAI;AACJ,MAAI,UAAgC,CAAC;AAErC,MAAI,OAAO,iCAAiC,UAAU;AAEpD,kBAAc;AACd,QAAI,wBAAwB,OAAO,yBAAyB,UAAU;AACpE,gBAAU;AAAA,IACZ;AAAA,EACF,WAAW,gCAAgC,OAAO,iCAAiC,UAAU;AAE3F,cAAU;AAAA,EACZ;AAEA,SAAO,2CAA2C,SAAS,WAAW;AACxE;AAEO,MAAM,iBAAiB;AAEvB,MAAM,kDAAkD,CAAC,WAA+D;AAC7H,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,SAAO,yBAAa,eAAe,wDAAwD,WAAW;AACxG;AAQO,MAAM,2BAA8D;AAAA,EACzE,YAAY,gBAAqC;AAAA,EAEjD;AAAA;AAAA,EAGA,YAAY,eAA6E;AACvF,WAAO,gDAAgD,cAAc,KAAK;AAAA,EAC5E;AACF;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts"],
4
- "sourcesContent": ["import {ReflectUtils} from '@dooboostore/core';\nimport {Router} from '@dooboostore/core-web';\nimport {HelperHostSet} from '../types';\n\nexport const SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY = Symbol.for('simple-web-component:subscribe-swc-app-route-change-while-connected');\n\nexport type RoutePathType = string | string[] | ((currentThis: any) => string | string[]);\n\nexport interface SwcAppRouteChangeSubscriberMetadata {\n propertyKey: string | symbol;\n options?: SwcAppRouteChangeOptions;\n}\n\nexport interface SwcAppRouteChangeOptions {\n path?: RoutePathType;\n filter?: (router: Router, meta: { currentThis: any; helper: HelperHostSet }) => boolean;\n order?: number;\n valueKey?: symbol | string;\n}\n\nfunction createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteChangeOptions): MethodDecorator {\n return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {\n const pathPattern = options?.path;\n const filter = options?.filter;\n\n const constructor = target.constructor;\n let list = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor) as SwcAppRouteChangeSubscriberMetadata[];\n if (!list) {\n list = [];\n ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, list, constructor);\n }\n list.push({ propertyKey, options });\n\n return descriptor;\n };\n}\n\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uC9C1\uC811 \uC0AC\uC6A9 (\uAD04\uD638 \uC5C6\uC74C)\nexport function subscribeSwcAppRouteChangeWhileConnected(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;\n// \uC624\uBC84\uB85C\uB4DC \uC2DC\uADF8\uB2C8\uCC98 - \uD568\uC218 \uD638\uCD9C (\uAD04\uD638 \uC788\uC74C)\nexport function subscribeSwcAppRouteChangeWhileConnected(): MethodDecorator;\nexport function subscribeSwcAppRouteChangeWhileConnected(pathPattern: RoutePathType): MethodDecorator;\nexport function subscribeSwcAppRouteChangeWhileConnected(pathPattern: RoutePathType, config: Omit<SwcAppRouteChangeOptions, 'path'>): MethodDecorator;\nexport function subscribeSwcAppRouteChangeWhileConnected(options: SwcAppRouteChangeOptions): MethodDecorator;\n\n// \uC2E4\uC81C \uAD6C\uD604 (\uC774\uC911 \uBAA8\uB4DC)\nexport function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any, propertyKeyOrConfig?: any, descriptor?: PropertyDescriptor): any {\n // \uC9C1\uC811 \uB370\uCF54\uB808\uC774\uD130\uB85C \uC0AC\uC6A9\uB41C \uACBD\uC6B0 (\uAD04\uD638 \uC5C6\uC74C): @subscribeSwcAppRouteChangeWhileConnected\n // propertyKey\uAC00 string | symbol\uC774\uACE0 descriptor\uAC00 \uC788\uC73C\uBA74 \uC9C1\uC811 \uC0AC\uC6A9\n if (propertyKeyOrConfig && (typeof propertyKeyOrConfig === 'string' || typeof propertyKeyOrConfig === 'symbol')) {\n return createSubscribeSwcAppRouteChangeWhileConnected({})(targetOrOptions, propertyKeyOrConfig, descriptor);\n }\n\n // \uD568\uC218\uB85C \uD638\uCD9C\uB41C \uACBD\uC6B0 (\uAD04\uD638 \uC788\uC74C): @subscribeSwcAppRouteChangeWhileConnected() / @subscribeSwcAppRouteChangeWhileConnected('/path')\n let options: SwcAppRouteChangeOptions = {};\n\n if (Array.isArray(targetOrOptions)) {\n // \uBC30\uC5F4: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'])\n // \uB610\uB294: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'], { order: 1 })\n options.path = targetOrOptions;\n if (propertyKeyOrConfig && typeof propertyKeyOrConfig === 'object') {\n options = { ...options, ...propertyKeyOrConfig };\n }\n } else if (typeof targetOrOptions === 'string' || typeof targetOrOptions === 'function') {\n // \uBB38\uC790\uC5F4 \uB610\uB294 \uD568\uC218: @subscribeSwcAppRouteChangeWhileConnected('/path')\n // \uB610\uB294: @subscribeSwcAppRouteChangeWhileConnected('/path', { order: 1 })\n options.path = targetOrOptions;\n if (propertyKeyOrConfig && typeof propertyKeyOrConfig === 'object') {\n options = { ...options, ...propertyKeyOrConfig };\n }\n } else if (targetOrOptions && typeof targetOrOptions === 'object') {\n // \uAC1D\uCCB4: @subscribeSwcAppRouteChangeWhileConnected({ path: '/path', filter: ..., order: 1 })\n options = targetOrOptions;\n }\n\n return createSubscribeSwcAppRouteChangeWhileConnected(options);\n}\nexport const changedRoute = subscribeSwcAppRouteChangeWhileConnected;\n\n// Helper function to retrieve route change subscribers metadata\nexport const getSubscribeSwcAppRouteChangeWhileConnectedMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] => {\n const constructor = target instanceof Function ? target : target.constructor;\n const results = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor);\n if (!results) return [];\n \n // Sort by order (default 0 if not specified)\n return [...results].sort((a, b) => (a.options?.order ?? 0) - (b.options?.order ?? 0));\n};\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// RouteSubscribeLifeCycler\n// NOTE: \uC2E4\uC81C \uAD6C\uB3C5 \uB85C\uC9C1\uC740 SwcAppMixin._connected \uC5D0\uC11C \uCC98\uB9AC\uB41C\uB2E4.\n// \uC774 cycler \uB294 \uBA54\uD0C0\uB370\uC774\uD130 \uC811\uADFC \uC9C4\uC785\uC810 \uC5ED\uD560\uB9CC \uD558\uBA70,\n// \uD5A5\uD6C4 SwcAppMixin \uC5D0\uC11C \uB85C\uC9C1\uC744 \uBD84\uB9AC\uD560 \uB54C \uC774 \uD074\uB798\uC2A4\uB85C \uC774\uC804\uD55C\uB2E4.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nimport { ElementDefineLifeCycler } from '../types';\n\nexport class RouteSubscribeLifeCycler implements ElementDefineLifeCycler {\n onConnected(_helperHostSet: HelperHostSet): void {\n // \uC2E4\uC81C \uAD6C\uB3C5\uC740 SwcAppMixin._connected \uC5D0\uC11C \uCC98\uB9AC\n }\n\n /** SwcAppMixin \uC774 \uAD6C\uB3C5 \uB300\uC0C1 \uBA54\uD0C0\uB97C \uAEBC\uB0BC \uB54C \uC0AC\uC6A9 */\n getMetadata(helperHostSet: HelperHostSet): SwcAppRouteChangeSubscriberMetadata[] {\n return getSubscribeSwcAppRouteChangeWhileConnectedMetadata(helperHostSet.$this);\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA2B;AAIpB,MAAM,8DAA8D,OAAO,IAAI,qEAAqE;AAgB3J,SAAS,+CAA+C,SAAqD;AAC3G,SAAO,CAAC,QAAgB,aAA8B,eAAoC;AACxF,UAAM,cAAc,SAAS;AAC7B,UAAM,SAAS,SAAS;AAExB,UAAM,cAAc,OAAO;AAC3B,QAAI,OAAO,yBAAa,eAAe,6DAA6D,WAAW;AAC/G,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AACR,+BAAa,eAAe,6DAA6D,MAAM,WAAW;AAAA,IAC5G;AACA,SAAK,KAAK,EAAE,aAAa,QAAQ,CAAC;AAElC,WAAO;AAAA,EACT;AACF;AAWO,SAAS,yCAAyC,iBAAuB,qBAA2B,YAAsC;AAG/I,MAAI,wBAAwB,OAAO,wBAAwB,YAAY,OAAO,wBAAwB,WAAW;AAC/G,WAAO,+CAA+C,CAAC,CAAC,EAAE,iBAAiB,qBAAqB,UAAU;AAAA,EAC5G;AAGA,MAAI,UAAoC,CAAC;AAEzC,MAAI,MAAM,QAAQ,eAAe,GAAG;AAGlC,YAAQ,OAAO;AACf,QAAI,uBAAuB,OAAO,wBAAwB,UAAU;AAClE,gBAAU,EAAE,GAAG,SAAS,GAAG,oBAAoB;AAAA,IACjD;AAAA,EACF,WAAW,OAAO,oBAAoB,YAAY,OAAO,oBAAoB,YAAY;AAGvF,YAAQ,OAAO;AACf,QAAI,uBAAuB,OAAO,wBAAwB,UAAU;AAClE,gBAAU,EAAE,GAAG,SAAS,GAAG,oBAAoB;AAAA,IACjD;AAAA,EACF,WAAW,mBAAmB,OAAO,oBAAoB,UAAU;AAEjE,cAAU;AAAA,EACZ;AAEA,SAAO,+CAA+C,OAAO;AAC/D;AACO,MAAM,eAAe;AAGrB,MAAM,sDAAsD,CAAC,WAAuD;AACzH,QAAM,cAAc,kBAAkB,WAAW,SAAS,OAAO;AACjE,QAAM,UAAU,yBAAa,eAAe,6DAA6D,WAAW;AACpH,MAAI,CAAC,QAAS,QAAO,CAAC;AAGtB,SAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,SAAS,MAAM,EAAE,SAAS,SAAS,EAAE;AACtF;AAUO,MAAM,yBAA4D;AAAA,EACvE,YAAY,gBAAqC;AAAA,EAEjD;AAAA;AAAA,EAGA,YAAY,eAAqE;AAC/E,WAAO,oDAAoD,cAAc,KAAK;AAAA,EAChF;AACF;",
6
- "names": []
7
- }
@@ -1,285 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
- var RxJSOperatorsExample_exports = {};
19
- __export(RxJSOperatorsExample_exports, {
20
- AutoSaveEditor: () => AutoSaveEditor,
21
- FormInput: () => FormInput,
22
- InfiniteScroll: () => InfiniteScroll,
23
- KeyboardHandler: () => KeyboardHandler,
24
- LengthTracker: () => LengthTracker,
25
- MouseTracker: () => MouseTracker,
26
- ResponsiveLayout: () => ResponsiveLayout,
27
- SearchComponent: () => SearchComponent
28
- });
29
- module.exports = __toCommonJS(RxJSOperatorsExample_exports);
30
- var import_decorators = require("../decorators");
31
- var __decorate = function(decorators, target, key, desc) {
32
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
33
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
34
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
35
- return c > 3 && r && Object.defineProperty(target, key, r), r;
36
- };
37
- var __metadata = function(k, v) {
38
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
39
- };
40
- var _a, _b, _c, _d, _e, _f, _g, _h;
41
- let SearchComponent = class SearchComponent2 extends HTMLElement {
42
- constructor() {
43
- super(...arguments);
44
- this.results = [];
45
- }
46
- async onSearchInput(event) {
47
- const input = event.target;
48
- const query = input.value.trim();
49
- if (query.length > 2) {
50
- try {
51
- const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
52
- this.results = await response.json();
53
- this.renderResults();
54
- } catch (error) {
55
- console.error("Search failed:", error);
56
- }
57
- } else {
58
- this.results = [];
59
- this.renderResults();
60
- }
61
- }
62
- renderResults() {
63
- console.log("Rendering results:", this.results);
64
- }
65
- };
66
- __decorate([
67
- (0, import_decorators.addEventListener)("$this", "input", { debounceTime: 1e3 }),
68
- __metadata("design:type", Function),
69
- __metadata("design:paramtypes", [typeof (_a = typeof Event !== "undefined" && Event) === "function" ? _a : Object]),
70
- __metadata("design:returntype", Promise)
71
- ], SearchComponent.prototype, "onSearchInput", null);
72
- SearchComponent = __decorate([
73
- (0, import_decorators.elementDefine)("search-component")
74
- ], SearchComponent);
75
- let ResponsiveLayout = class ResponsiveLayout2 extends HTMLElement {
76
- onWindowResize(event) {
77
- const width = window.innerWidth;
78
- const height = window.innerHeight;
79
- console.log(`Window resized to: ${width}x${height}`);
80
- this.updateLayout(width, height);
81
- }
82
- updateLayout(width, height) {
83
- if (width < 768) {
84
- this.classList.add("mobile");
85
- this.classList.remove("desktop");
86
- } else {
87
- this.classList.add("desktop");
88
- this.classList.remove("mobile");
89
- }
90
- }
91
- };
92
- __decorate([
93
- (0, import_decorators.addEventListener)("$window", "resize", { throttleTime: 250 }),
94
- __metadata("design:type", Function),
95
- __metadata("design:paramtypes", [typeof (_b = typeof Event !== "undefined" && Event) === "function" ? _b : Object]),
96
- __metadata("design:returntype", void 0)
97
- ], ResponsiveLayout.prototype, "onWindowResize", null);
98
- ResponsiveLayout = __decorate([
99
- (0, import_decorators.elementDefine)("responsive-layout")
100
- ], ResponsiveLayout);
101
- let FormInput = class FormInput2 extends HTMLElement {
102
- onFormInput(event) {
103
- const input = event.target;
104
- const fieldName = input.name;
105
- const value = input.value;
106
- console.log(`Validating ${fieldName}: ${value}`);
107
- this.validateField(fieldName, value);
108
- }
109
- validateField(name, value) {
110
- const isValid = value.length > 0;
111
- console.log(`Field ${name} is ${isValid ? "valid" : "invalid"}`);
112
- }
113
- };
114
- __decorate([
115
- (0, import_decorators.addEventListener)("$this", "input", {
116
- debounceTime: 300,
117
- distinctUntilChanged: true
118
- }),
119
- __metadata("design:type", Function),
120
- __metadata("design:paramtypes", [typeof (_c = typeof Event !== "undefined" && Event) === "function" ? _c : Object]),
121
- __metadata("design:returntype", void 0)
122
- ], FormInput.prototype, "onFormInput", null);
123
- FormInput = __decorate([
124
- (0, import_decorators.elementDefine)("form-input")
125
- ], FormInput);
126
- let InfiniteScroll = class InfiniteScroll2 extends HTMLElement {
127
- constructor() {
128
- super(...arguments);
129
- this.isLoading = false;
130
- }
131
- onScroll(event) {
132
- if (this.isLoading)
133
- return;
134
- if (this.isNearBottom()) {
135
- console.log("Near bottom, loading more content...");
136
- this.loadMoreContent();
137
- }
138
- }
139
- isNearBottom() {
140
- const scrollTop = window.scrollY;
141
- const windowHeight = window.innerHeight;
142
- const documentHeight = document.documentElement.scrollHeight;
143
- return scrollTop + windowHeight >= documentHeight - 500;
144
- }
145
- async loadMoreContent() {
146
- this.isLoading = true;
147
- try {
148
- await new Promise((resolve) => setTimeout(resolve, 1e3));
149
- console.log("Content loaded");
150
- } finally {
151
- this.isLoading = false;
152
- }
153
- }
154
- };
155
- __decorate([
156
- (0, import_decorators.addEventListener)("$window", "scroll", { throttleTime: 100 }),
157
- __metadata("design:type", Function),
158
- __metadata("design:paramtypes", [typeof (_d = typeof Event !== "undefined" && Event) === "function" ? _d : Object]),
159
- __metadata("design:returntype", void 0)
160
- ], InfiniteScroll.prototype, "onScroll", null);
161
- InfiniteScroll = __decorate([
162
- (0, import_decorators.elementDefine)("infinite-scroll")
163
- ], InfiniteScroll);
164
- let LengthTracker = class LengthTracker2 extends HTMLElement {
165
- onInputChange(event) {
166
- const input = event.target;
167
- const length = input.value.length;
168
- console.log(`Input length changed to: ${length}`);
169
- this.updateLengthDisplay(length);
170
- }
171
- updateLengthDisplay(length) {
172
- const display = this.querySelector(".length-display");
173
- if (display) {
174
- display.textContent = `${length} characters`;
175
- }
176
- }
177
- };
178
- __decorate([
179
- (0, import_decorators.addEventListener)("$this", "input", {
180
- distinctUntilChanged: (prev, curr) => {
181
- return prev?.length === curr?.length;
182
- }
183
- }),
184
- __metadata("design:type", Function),
185
- __metadata("design:paramtypes", [typeof (_e = typeof Event !== "undefined" && Event) === "function" ? _e : Object]),
186
- __metadata("design:returntype", void 0)
187
- ], LengthTracker.prototype, "onInputChange", null);
188
- LengthTracker = __decorate([
189
- (0, import_decorators.elementDefine)("length-tracker")
190
- ], LengthTracker);
191
- let AutoSaveEditor = class AutoSaveEditor2 extends HTMLElement {
192
- constructor() {
193
- super(...arguments);
194
- this.lastSavedContent = "";
195
- }
196
- async onContentChange(event) {
197
- const textarea = event.target;
198
- const content = textarea.value;
199
- if (content !== this.lastSavedContent) {
200
- console.log("Auto-saving content...");
201
- await this.saveContent(content);
202
- this.lastSavedContent = content;
203
- }
204
- }
205
- async saveContent(content) {
206
- try {
207
- const response = await fetch("/api/save", {
208
- method: "POST",
209
- headers: { "Content-Type": "application/json" },
210
- body: JSON.stringify({ content })
211
- });
212
- if (response.ok) {
213
- console.log("Content saved successfully");
214
- this.showSaveIndicator();
215
- }
216
- } catch (error) {
217
- console.error("Save failed:", error);
218
- }
219
- }
220
- showSaveIndicator() {
221
- const indicator = this.querySelector(".save-indicator");
222
- if (indicator) {
223
- indicator.classList.add("show");
224
- setTimeout(() => indicator.classList.remove("show"), 2e3);
225
- }
226
- }
227
- };
228
- __decorate([
229
- (0, import_decorators.addEventListener)("$this", "input", {
230
- debounceTime: 2e3,
231
- distinctUntilChanged: (prev, curr) => {
232
- return prev === curr;
233
- }
234
- }),
235
- __metadata("design:type", Function),
236
- __metadata("design:paramtypes", [typeof (_f = typeof Event !== "undefined" && Event) === "function" ? _f : Object]),
237
- __metadata("design:returntype", Promise)
238
- ], AutoSaveEditor.prototype, "onContentChange", null);
239
- AutoSaveEditor = __decorate([
240
- (0, import_decorators.elementDefine)("auto-save-editor")
241
- ], AutoSaveEditor);
242
- let KeyboardHandler = class KeyboardHandler2 extends HTMLElement {
243
- onSaveShortcut(event) {
244
- event.preventDefault();
245
- console.log("Save shortcut triggered");
246
- this.handleSave();
247
- }
248
- handleSave() {
249
- console.log("Saving...");
250
- }
251
- };
252
- __decorate([
253
- (0, import_decorators.addEventListener)("$document", "keydown", {
254
- throttleTime: 500,
255
- filter: (event) => {
256
- return (event.ctrlKey || event.metaKey) && event.key === "s";
257
- }
258
- }),
259
- __metadata("design:type", Function),
260
- __metadata("design:paramtypes", [typeof (_g = typeof KeyboardEvent !== "undefined" && KeyboardEvent) === "function" ? _g : Object]),
261
- __metadata("design:returntype", void 0)
262
- ], KeyboardHandler.prototype, "onSaveShortcut", null);
263
- KeyboardHandler = __decorate([
264
- (0, import_decorators.elementDefine)("keyboard-handler")
265
- ], KeyboardHandler);
266
- let MouseTracker = class MouseTracker2 extends HTMLElement {
267
- onMouseMove(event) {
268
- const x = event.clientX;
269
- const y = event.clientY;
270
- this.updateCursorPosition(x, y);
271
- }
272
- updateCursorPosition(x, y) {
273
- console.log(`Cursor at: ${x}, ${y}`);
274
- }
275
- };
276
- __decorate([
277
- (0, import_decorators.addEventListener)("$document", "mousemove", { throttleTime: 100 }),
278
- __metadata("design:type", Function),
279
- __metadata("design:paramtypes", [typeof (_h = typeof MouseEvent !== "undefined" && MouseEvent) === "function" ? _h : Object]),
280
- __metadata("design:returntype", void 0)
281
- ], MouseTracker.prototype, "onMouseMove", null);
282
- MouseTracker = __decorate([
283
- (0, import_decorators.elementDefine)("mouse-tracker")
284
- ], MouseTracker);
285
- //# sourceMappingURL=RxJSOperatorsExample.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../src/examples/RxJSOperatorsExample.ts"],
4
- "sourcesContent": ["/**\n * Example: Using RxJS-like Operators with @addEventListener\n * \n * This example demonstrates how to use debounceTime, throttleTime, and distinctUntilChanged\n * operators with the @addEventListener decorator.\n */\n\nimport { elementDefine, addEventListener } from '../decorators';\n\n/**\n * Example 1: Search Component with Debounce\n * \n * Waits 1 second after user stops typing before performing search.\n * Prevents excessive API calls during typing.\n */\n@elementDefine('search-component')\nexport class SearchComponent extends HTMLElement {\n private results: any[] = [];\n\n @addEventListener('$this', 'input', { debounceTime: 1000 })\n async onSearchInput(event: Event) {\n const input = event.target as HTMLInputElement;\n const query = input.value.trim();\n\n if (query.length > 2) {\n try {\n // Simulate API call\n const response = await fetch(`/api/search?q=${encodeURIComponent(query)}`);\n this.results = await response.json();\n this.renderResults();\n } catch (error) {\n console.error('Search failed:', error);\n }\n } else {\n this.results = [];\n this.renderResults();\n }\n }\n\n private renderResults() {\n // Render search results\n console.log('Rendering results:', this.results);\n }\n}\n\n/**\n * Example 2: Window Resize Handler with Throttle\n * \n * Recalculates layout at most 4 times per second (every 250ms).\n * Prevents performance issues from excessive resize calculations.\n */\n@elementDefine('responsive-layout')\nexport class ResponsiveLayout extends HTMLElement {\n @addEventListener('$window', 'resize', { throttleTime: 250 })\n onWindowResize(event: Event) {\n const width = window.innerWidth;\n const height = window.innerHeight;\n\n console.log(`Window resized to: ${width}x${height}`);\n this.updateLayout(width, height);\n }\n\n private updateLayout(width: number, height: number) {\n // Update layout based on new dimensions\n if (width < 768) {\n this.classList.add('mobile');\n this.classList.remove('desktop');\n } else {\n this.classList.add('desktop');\n this.classList.remove('mobile');\n }\n }\n}\n\n/**\n * Example 3: Form Input with Debounce + Distinct\n * \n * Validates field only when:\n * 1. User stops typing (debounce 300ms)\n * 2. AND the value actually changed (distinct)\n */\n@elementDefine('form-input')\nexport class FormInput extends HTMLElement {\n @addEventListener('$this', 'input', {\n debounceTime: 300,\n distinctUntilChanged: true\n })\n onFormInput(event: Event) {\n const input = event.target as HTMLInputElement;\n const fieldName = input.name;\n const value = input.value;\n\n console.log(`Validating ${fieldName}: ${value}`);\n this.validateField(fieldName, value);\n }\n\n private validateField(name: string, value: string) {\n // Perform validation\n const isValid = value.length > 0;\n console.log(`Field ${name} is ${isValid ? 'valid' : 'invalid'}`);\n }\n}\n\n/**\n * Example 4: Scroll Event with Throttle\n * \n * Checks if user scrolled to bottom at most 10 times per second.\n * Prevents excessive \"load more\" API calls.\n */\n@elementDefine('infinite-scroll')\nexport class InfiniteScroll extends HTMLElement {\n private isLoading = false;\n\n @addEventListener('$window', 'scroll', { throttleTime: 100 })\n onScroll(event: Event) {\n if (this.isLoading) return;\n\n if (this.isNearBottom()) {\n console.log('Near bottom, loading more content...');\n this.loadMoreContent();\n }\n }\n\n private isNearBottom(): boolean {\n const scrollTop = window.scrollY;\n const windowHeight = window.innerHeight;\n const documentHeight = document.documentElement.scrollHeight;\n\n return scrollTop + windowHeight >= documentHeight - 500;\n }\n\n private async loadMoreContent() {\n this.isLoading = true;\n try {\n // Simulate API call\n await new Promise(resolve => setTimeout(resolve, 1000));\n console.log('Content loaded');\n } finally {\n this.isLoading = false;\n }\n }\n}\n\n/**\n * Example 5: Custom Comparison with Distinct\n * \n * Only fires when the input value length changes.\n * Ignores changes that don't affect the length.\n */\n@elementDefine('length-tracker')\nexport class LengthTracker extends HTMLElement {\n @addEventListener('$this', 'input', {\n distinctUntilChanged: (prev: any, curr: any) => {\n // Only consider it changed if the length differs\n return prev?.length === curr?.length;\n }\n })\n onInputChange(event: Event) {\n const input = event.target as HTMLInputElement;\n const length = input.value.length;\n\n console.log(`Input length changed to: ${length}`);\n this.updateLengthDisplay(length);\n }\n\n private updateLengthDisplay(length: number) {\n // Update UI with new length\n const display = this.querySelector('.length-display');\n if (display) {\n display.textContent = `${length} characters`;\n }\n }\n}\n\n/**\n * Example 6: Complex Scenario - Auto-save with Multiple Operators\n * \n * Combines debounce and distinct for intelligent auto-save:\n * - Waits 2 seconds after user stops typing\n * - Only saves if content actually changed\n * - Prevents unnecessary save operations\n */\n@elementDefine('auto-save-editor')\nexport class AutoSaveEditor extends HTMLElement {\n private lastSavedContent = '';\n\n @addEventListener('$this', 'input', {\n debounceTime: 2000,\n distinctUntilChanged: (prev: any, curr: any) => {\n // Consider changed if the content is different\n return prev === curr;\n }\n })\n async onContentChange(event: Event) {\n const textarea = event.target as HTMLTextAreaElement;\n const content = textarea.value;\n\n if (content !== this.lastSavedContent) {\n console.log('Auto-saving content...');\n await this.saveContent(content);\n this.lastSavedContent = content;\n }\n }\n\n private async saveContent(content: string) {\n try {\n // Simulate API call\n const response = await fetch('/api/save', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ content })\n });\n\n if (response.ok) {\n console.log('Content saved successfully');\n this.showSaveIndicator();\n }\n } catch (error) {\n console.error('Save failed:', error);\n }\n }\n\n private showSaveIndicator() {\n const indicator = this.querySelector('.save-indicator');\n if (indicator) {\n indicator.classList.add('show');\n setTimeout(() => indicator.classList.remove('show'), 2000);\n }\n }\n}\n\n/**\n * Example 7: Keyboard Shortcut Handler with Throttle\n * \n * Prevents rapid repeated execution of keyboard shortcuts.\n */\n@elementDefine('keyboard-handler')\nexport class KeyboardHandler extends HTMLElement {\n @addEventListener('$document', 'keydown', {\n throttleTime: 500,\n filter: (event: KeyboardEvent) => {\n // Only handle Ctrl+S or Cmd+S\n return (event.ctrlKey || event.metaKey) && event.key === 's';\n }\n })\n onSaveShortcut(event: KeyboardEvent) {\n event.preventDefault();\n console.log('Save shortcut triggered');\n this.handleSave();\n }\n\n private handleSave() {\n // Handle save operation\n console.log('Saving...');\n }\n}\n\n/**\n * Example 8: Mouse Move Tracking with Throttle\n * \n * Tracks mouse position at most 10 times per second.\n * Useful for analytics or interactive features.\n */\n@elementDefine('mouse-tracker')\nexport class MouseTracker extends HTMLElement {\n @addEventListener('$document', 'mousemove', { throttleTime: 100 })\n onMouseMove(event: MouseEvent) {\n const x = event.clientX;\n const y = event.clientY;\n\n // Update cursor position indicator\n this.updateCursorPosition(x, y);\n }\n\n private updateCursorPosition(x: number, y: number) {\n // Update UI with cursor position\n console.log(`Cursor at: ${x}, ${y}`);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["SearchComponent", "ResponsiveLayout", "FormInput", "InfiniteScroll", "LengthTracker", "AutoSaveEditor", "KeyboardHandler", "MouseTracker"]
7
- }