@dooboostore/simple-web-component 1.0.48 → 1.0.49

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 (150) hide show
  1. package/README.md +117 -19
  2. package/dist/cjs/config/config.js +1 -1
  3. package/dist/cjs/config/config.js.map +2 -2
  4. package/dist/cjs/decorators/addEventListener.js +387 -29
  5. package/dist/cjs/decorators/addEventListener.js.map +3 -3
  6. package/dist/cjs/decorators/applyAttribute.js +25 -0
  7. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  8. package/dist/cjs/decorators/applyClass.js +49 -18
  9. package/dist/cjs/decorators/applyClass.js.map +3 -3
  10. package/dist/cjs/decorators/applyNode.js +67 -1
  11. package/dist/cjs/decorators/applyNode.js.map +3 -3
  12. package/dist/cjs/decorators/applyProperty.js +101 -3
  13. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  14. package/dist/cjs/decorators/applyStyle.js +36 -5
  15. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  16. package/dist/cjs/decorators/changedAttribute.js +39 -0
  17. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  18. package/dist/cjs/decorators/elementDefine.js +237 -437
  19. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  20. package/dist/cjs/decorators/emitCustomEvent.js +55 -0
  21. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  22. package/dist/cjs/decorators/index.js +3 -1
  23. package/dist/cjs/decorators/index.js.map +2 -2
  24. package/dist/cjs/decorators/intersectionObserver.js +209 -0
  25. package/dist/cjs/decorators/intersectionObserver.js.map +7 -0
  26. package/dist/cjs/decorators/mutationObserver.js +140 -0
  27. package/dist/cjs/decorators/mutationObserver.js.map +3 -3
  28. package/dist/cjs/decorators/query.js +117 -102
  29. package/dist/cjs/decorators/query.js.map +2 -2
  30. package/dist/cjs/decorators/resizeObserver.js +87 -0
  31. package/dist/cjs/decorators/resizeObserver.js.map +2 -2
  32. package/dist/cjs/decorators/setInterval.js +82 -0
  33. package/dist/cjs/decorators/setInterval.js.map +7 -0
  34. package/dist/cjs/decorators/setTimeout.js +82 -0
  35. package/dist/cjs/decorators/setTimeout.js.map +7 -0
  36. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +9 -0
  37. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  38. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +9 -0
  39. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  40. package/dist/cjs/types/index.js.map +1 -1
  41. package/dist/esm/config/config.js +1 -1
  42. package/dist/esm/config/config.js.map +2 -2
  43. package/dist/esm/decorators/addEventListener.js +388 -29
  44. package/dist/esm/decorators/addEventListener.js.map +3 -3
  45. package/dist/esm/decorators/applyAttribute.js +25 -0
  46. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  47. package/dist/esm/decorators/applyClass.js +49 -18
  48. package/dist/esm/decorators/applyClass.js.map +3 -3
  49. package/dist/esm/decorators/applyNode.js +67 -1
  50. package/dist/esm/decorators/applyNode.js.map +3 -3
  51. package/dist/esm/decorators/applyProperty.js +101 -3
  52. package/dist/esm/decorators/applyProperty.js.map +2 -2
  53. package/dist/esm/decorators/applyStyle.js +36 -5
  54. package/dist/esm/decorators/applyStyle.js.map +2 -2
  55. package/dist/esm/decorators/changedAttribute.js +40 -0
  56. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  57. package/dist/esm/decorators/elementDefine.js +244 -444
  58. package/dist/esm/decorators/elementDefine.js.map +3 -3
  59. package/dist/esm/decorators/emitCustomEvent.js +55 -0
  60. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  61. package/dist/esm/decorators/index.js +3 -1
  62. package/dist/esm/decorators/index.js.map +2 -2
  63. package/dist/esm/decorators/intersectionObserver.js +191 -0
  64. package/dist/esm/decorators/intersectionObserver.js.map +7 -0
  65. package/dist/esm/decorators/mutationObserver.js +141 -0
  66. package/dist/esm/decorators/mutationObserver.js.map +3 -3
  67. package/dist/esm/decorators/query.js +117 -102
  68. package/dist/esm/decorators/query.js.map +2 -2
  69. package/dist/esm/decorators/resizeObserver.js +88 -0
  70. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  71. package/dist/esm/decorators/setInterval.js +64 -0
  72. package/dist/esm/decorators/setInterval.js.map +7 -0
  73. package/dist/esm/decorators/setTimeout.js +64 -0
  74. package/dist/esm/decorators/setTimeout.js.map +7 -0
  75. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +9 -0
  76. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  77. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +9 -0
  78. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  79. package/dist/esm/types/index.js.map +1 -1
  80. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +2565 -1474
  81. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  82. package/dist/types/config/config.d.ts.map +1 -1
  83. package/dist/types/decorators/addEventListener.d.ts +84 -33
  84. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  85. package/dist/types/decorators/applyAttribute.d.ts +22 -34
  86. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  87. package/dist/types/decorators/applyClass.d.ts +34 -34
  88. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  89. package/dist/types/decorators/applyNode.d.ts +30 -20
  90. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  91. package/dist/types/decorators/applyProperty.d.ts +57 -34
  92. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  93. package/dist/types/decorators/applyStyle.d.ts +25 -12
  94. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  95. package/dist/types/decorators/changedAttribute.d.ts +11 -0
  96. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  97. package/dist/types/decorators/elementDefine.d.ts +0 -14
  98. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  99. package/dist/types/decorators/emitCustomEvent.d.ts +28 -4
  100. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  101. package/dist/types/decorators/index.d.ts +3 -1
  102. package/dist/types/decorators/index.d.ts.map +1 -1
  103. package/dist/types/decorators/intersectionObserver.d.ts +49 -0
  104. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -0
  105. package/dist/types/decorators/mutationObserver.d.ts +35 -25
  106. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  107. package/dist/types/decorators/query.d.ts +57 -14
  108. package/dist/types/decorators/query.d.ts.map +1 -1
  109. package/dist/types/decorators/resizeObserver.d.ts +34 -23
  110. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  111. package/dist/types/decorators/setInterval.d.ts +29 -0
  112. package/dist/types/decorators/setInterval.d.ts.map +1 -0
  113. package/dist/types/decorators/setTimeout.d.ts +29 -0
  114. package/dist/types/decorators/setTimeout.d.ts.map +1 -0
  115. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +7 -1
  116. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  117. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +6 -0
  118. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  119. package/dist/types/types/index.d.ts +104 -0
  120. package/dist/types/types/index.d.ts.map +1 -1
  121. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +2565 -1474
  122. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  123. package/package.json +7 -5
  124. package/src/config/config.ts +1 -1
  125. package/src/decorators/addEventListener.ts +394 -34
  126. package/src/decorators/applyAttribute.ts +50 -36
  127. package/src/decorators/applyClass.ts +76 -26
  128. package/src/decorators/applyNode.ts +114 -36
  129. package/src/decorators/applyProperty.ts +152 -40
  130. package/src/decorators/applyStyle.ts +64 -17
  131. package/src/decorators/changedAttribute.ts +46 -0
  132. package/src/decorators/elementDefine.ts +281 -580
  133. package/src/decorators/emitCustomEvent.ts +73 -5
  134. package/src/decorators/index.ts +3 -1
  135. package/src/decorators/intersectionObserver.ts +259 -0
  136. package/src/decorators/mutationObserver.ts +215 -39
  137. package/src/decorators/query.ts +168 -126
  138. package/src/decorators/resizeObserver.ts +152 -46
  139. package/src/decorators/setInterval.ts +80 -0
  140. package/src/decorators/setTimeout.ts +80 -0
  141. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +17 -0
  142. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +19 -0
  143. package/src/types/index.ts +141 -0
  144. package/dist/cjs/decorators/queryAll.js +0 -181
  145. package/dist/cjs/decorators/queryAll.js.map +0 -7
  146. package/dist/esm/decorators/queryAll.js +0 -162
  147. package/dist/esm/decorators/queryAll.js.map +0 -7
  148. package/dist/types/decorators/queryAll.d.ts +0 -22
  149. package/dist/types/decorators/queryAll.d.ts.map +0 -1
  150. package/src/decorators/queryAll.ts +0 -186
@@ -1,35 +1,40 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
- import { SpecialSelector, SwcQueryOptions, HelperHostSet } from '../types';
3
- import { EventListenerSelector } from './addEventListener';
4
-
5
- export interface MutationObserverBaseOptions extends MutationObserverInit, SwcQueryOptions {
6
- // observe 대상 셀렉터. 기본값 $this (컴포넌트 자신)
7
- // delegate: true 인 경우 root에 observer를 걸고 셀렉터 매칭 대상의 mutation만 콜백
8
- // 셀렉터로 직접 지정한 경우 해당 요소들을 각각 observe
9
- delegate?: boolean;
2
+ import { SpecialSelector, SwcQueryOptions, SwcSelector, SwcFnSelector, HelperHostSet } from '../types';
3
+
4
+ // 공통 옵션 — root·delegate 없음 (MutationObserverInit + filter/removeObserver)
5
+ export interface MutationObserverBaseOptions extends MutationObserverInit {
10
6
  filter?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => boolean;
11
7
  // observer 해제(disconnected) 시 호출되는 콜백. 첫 번째 인자는 observe된 target element, 두 번째는 사용자 옵션 객체.
12
- removeObserver?: (target: Element, optionValue: MutationObserverBaseOptions) => void;
8
+ removeObserver?: (target: Element, optionValue: MutationObserverQueryOptions) => void;
13
9
  }
14
10
 
11
+ // 문자열 셀렉터 전용 — root·delegate 허용 (셀렉터로 탐색/델리게이션)
12
+ export type MutationObserverQueryOptions = MutationObserverBaseOptions & SwcQueryOptions & { delegate?: boolean };
13
+ // 함수 셀렉터 전용 — root·delegate 금지 (이미 요소를 직접 반환)
14
+ export type MutationObserverNonQueryOptions = MutationObserverBaseOptions;
15
+
16
+ // 셀렉터 종류에 따라 옵션 타입 분기
17
+ export type MutationObserverOptionsOf<S extends SwcSelector> = S extends string ? MutationObserverQueryOptions : MutationObserverNonQueryOptions;
18
+
15
19
  export interface MutationObserverMetadata {
16
20
  propertyKey: string | symbol;
17
- selector: EventListenerSelector;
18
- options: MutationObserverBaseOptions;
21
+ selector: SwcSelector;
22
+ options: MutationObserverQueryOptions;
19
23
  }
20
24
 
21
25
  export const MUTATION_OBSERVER_METADATA_KEY = Symbol.for('simple-web-component:mutation-observer');
22
26
 
23
- export function mutationObserver(target: SpecialSelector, options?: MutationObserverBaseOptions): MethodDecorator;
24
- export function mutationObserver(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
25
- export function mutationObserver(options?: MutationObserverBaseOptions): MethodDecorator;
27
+ export function mutationObserver(target: SpecialSelector, options?: MutationObserverQueryOptions): MethodDecorator;
28
+ export function mutationObserver(selector: string, options?: MutationObserverQueryOptions): MethodDecorator;
29
+ export function mutationObserver(selector: SwcFnSelector, options?: MutationObserverNonQueryOptions): MethodDecorator;
30
+ export function mutationObserver(options?: MutationObserverQueryOptions): MethodDecorator;
26
31
  /**
27
32
  * @mutationObserver decorator to observe DOM mutations.
28
33
  */
29
- export function mutationObserver(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
34
+ export function mutationObserver(selectorOrOptions?: SwcSelector | MutationObserverQueryOptions, maybeOptions?: MutationObserverQueryOptions): MethodDecorator {
30
35
  return (targetObj: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
31
- let selector: EventListenerSelector = '$this';
32
- let options: MutationObserverBaseOptions = {};
36
+ let selector: SwcSelector = '$this';
37
+ let options: MutationObserverQueryOptions = {};
33
38
 
34
39
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
35
40
  selector = selectorOrOptions;
@@ -51,42 +56,42 @@ export function mutationObserver(selectorOrOptions?: EventListenerSelector | Mut
51
56
  };
52
57
  }
53
58
 
54
- export function mutationObserverThis<TEvent extends Event = Event>(options?: MutationObserverBaseOptions): MethodDecorator {
59
+ export function mutationObserverThis<TEvent extends Event = Event>(options?: MutationObserverQueryOptions): MethodDecorator {
55
60
  return mutationObserver('$this', options);
56
61
  }
57
62
 
58
63
  // ─── root별 delegate 헬퍼 (addEventListener와 동일 패턴) ───
59
64
 
60
- export function mutationObserverDelegateLight(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
61
- export function mutationObserverDelegateLight(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
62
- export function mutationObserverDelegateLight(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
65
+ export function mutationObserverDelegateLight(selector: string, options?: MutationObserverBaseOptions): MethodDecorator;
66
+ export function mutationObserverDelegateLight(options?: MutationObserverBaseOptions): MethodDecorator;
67
+ export function mutationObserverDelegateLight(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
63
68
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
64
69
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light', delegate: true});
65
70
  }
66
71
  return mutationObserver({...selectorOrOptions ?? {}, root: 'light', delegate: true});
67
72
  }
68
73
 
69
- export function mutationObserverDelegateShadow(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
70
- export function mutationObserverDelegateShadow(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
71
- export function mutationObserverDelegateShadow(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
74
+ export function mutationObserverDelegateShadow(selector: string, options?: MutationObserverBaseOptions): MethodDecorator;
75
+ export function mutationObserverDelegateShadow(options?: MutationObserverBaseOptions): MethodDecorator;
76
+ export function mutationObserverDelegateShadow(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
72
77
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
73
78
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow', delegate: true});
74
79
  }
75
80
  return mutationObserver({...selectorOrOptions ?? {}, root: 'shadow', delegate: true});
76
81
  }
77
82
 
78
- export function mutationObserverDelegateAll(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
79
- export function mutationObserverDelegateAll(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
80
- export function mutationObserverDelegateAll(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
83
+ export function mutationObserverDelegateAll(selector: string, options?: MutationObserverBaseOptions): MethodDecorator;
84
+ export function mutationObserverDelegateAll(options?: MutationObserverBaseOptions): MethodDecorator;
85
+ export function mutationObserverDelegateAll(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
81
86
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
82
87
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all', delegate: true});
83
88
  }
84
89
  return mutationObserver({...selectorOrOptions ?? {}, root: 'all', delegate: true});
85
90
  }
86
91
 
87
- export function mutationObserverDelegate(selector: EventListenerSelector, options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
88
- export function mutationObserverDelegate(options?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator;
89
- export function mutationObserverDelegate(selectorOrOptions?: EventListenerSelector | Omit<MutationObserverBaseOptions, 'delegate'>, maybeOptions?: Omit<MutationObserverBaseOptions, 'delegate'>): MethodDecorator {
92
+ export function mutationObserverDelegate(selector: string, options?: MutationObserverBaseOptions): MethodDecorator;
93
+ export function mutationObserverDelegate(options?: MutationObserverBaseOptions): MethodDecorator;
94
+ export function mutationObserverDelegate(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
90
95
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
91
96
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'auto', delegate: true});
92
97
  }
@@ -95,27 +100,27 @@ export function mutationObserverDelegate(selectorOrOptions?: EventListenerSelect
95
100
 
96
101
  // ─── root별 일반 헬퍼 (delegate 없이, 셀렉터 생략 시 $this) ───
97
102
 
98
- export function mutationObserverLight(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
99
- export function mutationObserverLight(options?: MutationObserverBaseOptions): MethodDecorator;
100
- export function mutationObserverLight(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
103
+ export function mutationObserverLight(selector: string, options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
104
+ export function mutationObserverLight(options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
105
+ export function mutationObserverLight(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
101
106
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
102
107
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'light'});
103
108
  }
104
109
  return mutationObserver({...selectorOrOptions ?? {}, root: 'light'});
105
110
  }
106
111
 
107
- export function mutationObserverShadow(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
108
- export function mutationObserverShadow(options?: MutationObserverBaseOptions): MethodDecorator;
109
- export function mutationObserverShadow(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
112
+ export function mutationObserverShadow(selector: string, options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
113
+ export function mutationObserverShadow(options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
114
+ export function mutationObserverShadow(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
110
115
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
111
116
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'shadow'});
112
117
  }
113
118
  return mutationObserver({...selectorOrOptions ?? {}, root: 'shadow'});
114
119
  }
115
120
 
116
- export function mutationObserverAll(selector: EventListenerSelector, options?: MutationObserverBaseOptions): MethodDecorator;
117
- export function mutationObserverAll(options?: MutationObserverBaseOptions): MethodDecorator;
118
- export function mutationObserverAll(selectorOrOptions?: EventListenerSelector | MutationObserverBaseOptions, maybeOptions?: MutationObserverBaseOptions): MethodDecorator {
121
+ export function mutationObserverAll(selector: string, options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
122
+ export function mutationObserverAll(options?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator;
123
+ export function mutationObserverAll(selectorOrOptions?: string | Omit<MutationObserverQueryOptions, 'root'>, maybeOptions?: Omit<MutationObserverQueryOptions, 'root'>): MethodDecorator {
119
124
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
120
125
  return mutationObserver(selectorOrOptions, {...maybeOptions ?? {}, root: 'all'});
121
126
  }
@@ -125,4 +130,175 @@ export function mutationObserverAll(selectorOrOptions?: EventListenerSelector |
125
130
  export function getMutationObserverMetadata(target: any): MutationObserverMetadata[] | undefined {
126
131
  const constructor = target instanceof Function ? target : target.constructor;
127
132
  return ReflectUtils.getMetadata(MUTATION_OBSERVER_METADATA_KEY, constructor);
133
+ }
134
+
135
+ // ─────────────────────────────────────────────────────────────────────────────
136
+ // MutationObserverLifeCycler
137
+ // observer 를 직접 생성하지 않고 OnConnectedResult 를 반환한다.
138
+ // elementDefine 이 수집된 MutationObserverSet 으로 observer 를 생성한다.
139
+ // ─────────────────────────────────────────────────────────────────────────────
140
+ import { ElementDefineLifeCycler, MutationObserverSet, MutationObserverSetEntry, ObserverObserveTarget, OnConnectedResult } from '../types';
141
+ import { SwcUtils } from '../utils/Utils';
142
+
143
+ export class MutationObserverLifeCycler implements ElementDefineLifeCycler {
144
+ private readonly removeObserverCallbacksMap = new WeakMap<Element, Array<{ fn: (target: Element, opts: unknown) => void; target: any; opts: unknown }>>();
145
+
146
+ onConnected(helperHostSet: HelperHostSet): OnConnectedResult | void {
147
+ const inst = helperHostSet.$this;
148
+ const currentWin = helperHostSet.$w;
149
+
150
+ const removeObserverCallbacks: Array<{ fn: (target: Element, opts: unknown) => void; target: any; opts: unknown }> = [];
151
+ this.removeObserverCallbacksMap.set(inst, removeObserverCallbacks);
152
+
153
+ const allMeta = getMutationObserverMetadata(inst) ?? [];
154
+ // 처리할 메타가 없으면 observer 불필요
155
+ if (allMeta.length === 0) return;
156
+
157
+ // ── shadow / light 루트별 분류 ──
158
+ const shadowMetas = allMeta.filter(m => {
159
+ const r = m.options.root || 'auto';
160
+ return inst.shadowRoot && (r === 'shadow' || r === 'all' || r === 'auto');
161
+ });
162
+ const lightMetas = allMeta.filter(m => {
163
+ const r = m.options.root || 'auto';
164
+ return r === 'light' || r === 'all' || (!inst.shadowRoot && r === 'auto');
165
+ });
166
+ // ── MutationObserverSet 생성 헬퍼 (루트별) ──
167
+ const buildSet = (
168
+ root: HTMLElement | ShadowRoot,
169
+ metas: MutationObserverMetadata[],
170
+ ): { callback: MutationObserverSetEntry['callback']; observeTargets: ObserverObserveTarget<MutationObserverInit>[] } | null => {
171
+ if (metas.length === 0) return null;
172
+
173
+ const initFrom = (o: MutationObserverBaseOptions): MutationObserverInit => {
174
+ const init: MutationObserverInit = {
175
+ childList: o.childList, attributes: o.attributes, characterData: o.characterData,
176
+ subtree: o.subtree, attributeFilter: o.attributeFilter,
177
+ attributeOldValue: o.attributeOldValue, characterDataOldValue: o.characterDataOldValue,
178
+ };
179
+ if (!init.childList && !init.attributes && !init.characterData) init.childList = true;
180
+ return init;
181
+ };
182
+
183
+ const fnObservedSets = new Map<MutationObserverMetadata, WeakSet<Element>>();
184
+
185
+ const callback = (mutations: MutationRecord[], obs: MutationObserver) => {
186
+ // ── MutationObserver 메타 콜백 ──
187
+ for (const meta of metas) {
188
+ const { selector, options } = meta;
189
+ let matchedEls: HTMLElement[] = [];
190
+
191
+ const typeMatches = (m: MutationRecord): boolean => {
192
+ const has = !!(options.childList || options.attributes || options.characterData);
193
+ if (m.type === 'childList') return has ? !!options.childList : true;
194
+ if (m.type === 'attributes') return !!options.attributes;
195
+ if (m.type === 'characterData') return !!options.characterData;
196
+ return true;
197
+ };
198
+
199
+ const collect = (matchesSel: (n: any) => boolean) =>
200
+ mutations.flatMap(m => {
201
+ if (!typeMatches(m)) return [];
202
+ const els: HTMLElement[] = [];
203
+ if (matchesSel(m.target)) els.push(m.target as HTMLElement);
204
+ Array.from(m.addedNodes || []).filter(matchesSel).forEach(n => els.push(n as HTMLElement));
205
+ Array.from(m.removedNodes || []).filter(matchesSel).forEach(n => els.push(n as HTMLElement));
206
+ return els;
207
+ });
208
+
209
+ if (options.delegate && typeof selector === 'string') {
210
+ const isThis = selector === '$this' || selector === '';
211
+ matchedEls = collect(n => {
212
+ if (!n || n.nodeType !== 1) return false;
213
+ if (isThis) return true;
214
+ const el = n as HTMLElement;
215
+ return el.matches?.(selector) || !!el.closest?.(selector);
216
+ });
217
+ } else if (typeof selector === 'string') {
218
+ const isThis = selector === '$this' || selector === '';
219
+ matchedEls = collect(n => {
220
+ if (!n || n.nodeType !== 1) return false;
221
+ if (isThis) return true;
222
+ return (n as HTMLElement).matches?.(selector);
223
+ });
224
+ } else if (typeof selector === 'function') {
225
+ const set = fnObservedSets.get(meta);
226
+ matchedEls = mutations.filter(m => typeMatches(m))
227
+ .map(m => m.target as HTMLElement)
228
+ .filter(t => t && t.nodeType === 1 && (set ? set.has(t) : false));
229
+ } else {
230
+ matchedEls = mutations.filter(m => typeMatches(m))
231
+ .map(m => m.target as HTMLElement)
232
+ .filter(t => t && t.nodeType === 1);
233
+ }
234
+
235
+ if (matchedEls.length === 0) continue;
236
+ if (options.filter) {
237
+ if (!options.filter(matchedEls, { currentThis: inst, helper: helperHostSet })) continue;
238
+ }
239
+ const hostSet = SwcUtils.getHostSet(inst);
240
+ inst[meta.propertyKey](matchedEls, mutations, obs, { ...hostSet, $root: root });
241
+ }
242
+
243
+ };
244
+
245
+ // ── observe 대상 목록 구성 ──
246
+ const observeTargets: ObserverObserveTarget<MutationObserverInit>[] = [];
247
+
248
+ // delegate 있으면 루트 전체 subtree observe
249
+ if (metas.some(m => m.options.delegate)) {
250
+ observeTargets.push({ target: root, options: { childList: true, subtree: true } });
251
+ }
252
+
253
+ // non-delegate: 셀렉터 매칭 요소 직접 observe
254
+ for (const m of metas.filter(m => !m.options.delegate)) {
255
+ const { selector, options } = m;
256
+ const mInit = initFrom(options);
257
+ if (typeof selector === 'string') {
258
+ if (selector === '$this' || selector === '') {
259
+ observeTargets.push({ target: root, options: mInit });
260
+ } else {
261
+ root.querySelectorAll(selector).forEach(el => observeTargets.push({ target: el as Element, options: mInit }));
262
+ }
263
+ } else if (typeof selector === 'function') {
264
+ const res = (selector as any)(inst, helperHostSet);
265
+ let targets: HTMLElement[] = [];
266
+ if (res instanceof currentWin.HTMLElement) targets = [res as HTMLElement];
267
+ else if (res instanceof currentWin.NodeList) targets = Array.from(res as NodeList).filter((e: any) => e instanceof currentWin.HTMLElement) as HTMLElement[];
268
+ else if (Array.isArray(res)) targets = res.filter((e: any) => e instanceof currentWin.HTMLElement) as HTMLElement[];
269
+ const set = new WeakSet<Element>();
270
+ for (const el of targets) { set.add(el); observeTargets.push({ target: el, options: mInit }); }
271
+ fnObservedSets.set(m, set);
272
+ }
273
+ }
274
+
275
+ // removeObserver 콜백 수집
276
+ for (const m of metas) {
277
+ if (m.options.removeObserver) removeObserverCallbacks.push({ fn: m.options.removeObserver, target: root, opts: m.options });
278
+ }
279
+
280
+ return { callback, observeTargets };
281
+ };
282
+
283
+ const shadowSet = inst.shadowRoot ? buildSet(inst.shadowRoot, shadowMetas) : null;
284
+ const lightSet = buildSet(inst as any, lightMetas);
285
+
286
+ // 두 루트의 observe 대상 + 콜백을 엔트리 배열(MutationObserverSet)로 병합
287
+ // 같은 루트의 여러 대상은 같은 callback 을 공유한다.
288
+ const mutationObserverSet: MutationObserverSet = [
289
+ ...(shadowSet?.observeTargets ?? []).map(t => ({ ...t, callback: shadowSet!.callback })),
290
+ ...(lightSet?.observeTargets ?? []).map(t => ({ ...t, callback: lightSet!.callback })),
291
+ ];
292
+ if (mutationObserverSet.length === 0) return;
293
+
294
+ return { mutationObserverSet };
295
+ }
296
+
297
+ onDisconnected(helperHostSet: HelperHostSet): void {
298
+ const inst = helperHostSet.$this;
299
+ for (const cb of this.removeObserverCallbacksMap.get(inst) ?? []) {
300
+ try { cb.fn(cb.target, cb.opts); } catch (e) { console.error('[SWC] removeObserver error:', e); }
301
+ }
302
+ this.removeObserverCallbacksMap.delete(inst);
303
+ }
128
304
  }