@dooboostore/simple-web-component 1.0.48 → 1.0.50

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 (192) hide show
  1. package/README.md +189 -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 +2373 -30
  5. package/dist/cjs/decorators/addEventListener.js.map +3 -3
  6. package/dist/cjs/decorators/applyAttribute.js +31 -0
  7. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  8. package/dist/cjs/decorators/applyClass.js +55 -18
  9. package/dist/cjs/decorators/applyClass.js.map +3 -3
  10. package/dist/cjs/decorators/applyNode.js +73 -1
  11. package/dist/cjs/decorators/applyNode.js.map +3 -3
  12. package/dist/cjs/decorators/applyProperty.js +107 -3
  13. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  14. package/dist/cjs/decorators/applySlot.js +6 -5
  15. package/dist/cjs/decorators/applySlot.js.map +2 -2
  16. package/dist/cjs/decorators/applyStyle.js +42 -5
  17. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  18. package/dist/cjs/decorators/changedAttribute.js +61 -13
  19. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  20. package/dist/cjs/decorators/elementDefine.js +254 -439
  21. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  22. package/dist/cjs/decorators/emitCustomEvent.js +55 -0
  23. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  24. package/dist/cjs/decorators/eventMedia.js +84 -0
  25. package/dist/cjs/decorators/eventMedia.js.map +7 -0
  26. package/dist/cjs/decorators/index.js +6 -1
  27. package/dist/cjs/decorators/index.js.map +2 -2
  28. package/dist/cjs/decorators/intersectionObserver.js +200 -0
  29. package/dist/cjs/decorators/intersectionObserver.js.map +7 -0
  30. package/dist/cjs/decorators/mutationObserver.js +186 -55
  31. package/dist/cjs/decorators/mutationObserver.js.map +3 -3
  32. package/dist/cjs/decorators/parameter.js +73 -0
  33. package/dist/cjs/decorators/parameter.js.map +7 -0
  34. package/dist/cjs/decorators/query.js +117 -102
  35. package/dist/cjs/decorators/query.js.map +2 -2
  36. package/dist/cjs/decorators/requestAnimationFrame.js +124 -0
  37. package/dist/cjs/decorators/requestAnimationFrame.js.map +7 -0
  38. package/dist/cjs/decorators/resizeObserver.js +133 -55
  39. package/dist/cjs/decorators/resizeObserver.js.map +2 -2
  40. package/dist/cjs/decorators/setInterval.js +114 -0
  41. package/dist/cjs/decorators/setInterval.js.map +7 -0
  42. package/dist/cjs/decorators/setTimeout.js +117 -0
  43. package/dist/cjs/decorators/setTimeout.js.map +7 -0
  44. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +9 -0
  45. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  46. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +9 -0
  47. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  48. package/dist/cjs/elements/SwcAppMixin.js +19 -3
  49. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  50. package/dist/cjs/types/index.js.map +1 -1
  51. package/dist/cjs/types/window.d.js.map +1 -1
  52. package/dist/esm/config/config.js +1 -1
  53. package/dist/esm/config/config.js.map +2 -2
  54. package/dist/esm/decorators/addEventListener.js +2374 -30
  55. package/dist/esm/decorators/addEventListener.js.map +3 -3
  56. package/dist/esm/decorators/applyAttribute.js +31 -0
  57. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  58. package/dist/esm/decorators/applyClass.js +55 -18
  59. package/dist/esm/decorators/applyClass.js.map +3 -3
  60. package/dist/esm/decorators/applyNode.js +73 -1
  61. package/dist/esm/decorators/applyNode.js.map +3 -3
  62. package/dist/esm/decorators/applyProperty.js +107 -3
  63. package/dist/esm/decorators/applyProperty.js.map +2 -2
  64. package/dist/esm/decorators/applySlot.js +6 -5
  65. package/dist/esm/decorators/applySlot.js.map +2 -2
  66. package/dist/esm/decorators/applyStyle.js +42 -5
  67. package/dist/esm/decorators/applyStyle.js.map +2 -2
  68. package/dist/esm/decorators/changedAttribute.js +62 -13
  69. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  70. package/dist/esm/decorators/elementDefine.js +261 -446
  71. package/dist/esm/decorators/elementDefine.js.map +3 -3
  72. package/dist/esm/decorators/emitCustomEvent.js +55 -0
  73. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  74. package/dist/esm/decorators/eventMedia.js +66 -0
  75. package/dist/esm/decorators/eventMedia.js.map +7 -0
  76. package/dist/esm/decorators/index.js +6 -1
  77. package/dist/esm/decorators/index.js.map +2 -2
  78. package/dist/esm/decorators/intersectionObserver.js +182 -0
  79. package/dist/esm/decorators/intersectionObserver.js.map +7 -0
  80. package/dist/esm/decorators/mutationObserver.js +187 -55
  81. package/dist/esm/decorators/mutationObserver.js.map +3 -3
  82. package/dist/esm/decorators/parameter.js +54 -0
  83. package/dist/esm/decorators/parameter.js.map +7 -0
  84. package/dist/esm/decorators/query.js +117 -102
  85. package/dist/esm/decorators/query.js.map +2 -2
  86. package/dist/esm/decorators/requestAnimationFrame.js +105 -0
  87. package/dist/esm/decorators/requestAnimationFrame.js.map +7 -0
  88. package/dist/esm/decorators/resizeObserver.js +134 -55
  89. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  90. package/dist/esm/decorators/setInterval.js +95 -0
  91. package/dist/esm/decorators/setInterval.js.map +7 -0
  92. package/dist/esm/decorators/setTimeout.js +98 -0
  93. package/dist/esm/decorators/setTimeout.js.map +7 -0
  94. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +9 -0
  95. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +2 -2
  96. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +9 -0
  97. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  98. package/dist/esm/elements/SwcAppMixin.js +20 -4
  99. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  100. package/dist/esm/types/index.js.map +1 -1
  101. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +4961 -1628
  102. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  103. package/dist/types/config/config.d.ts.map +1 -1
  104. package/dist/types/decorators/addEventListener.d.ts +1046 -33
  105. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  106. package/dist/types/decorators/applyAttribute.d.ts +24 -34
  107. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  108. package/dist/types/decorators/applyClass.d.ts +36 -34
  109. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  110. package/dist/types/decorators/applyNode.d.ts +32 -20
  111. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  112. package/dist/types/decorators/applyProperty.d.ts +61 -34
  113. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  114. package/dist/types/decorators/applySlot.d.ts.map +1 -1
  115. package/dist/types/decorators/applyStyle.d.ts +27 -12
  116. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  117. package/dist/types/decorators/changedAttribute.d.ts +12 -3
  118. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  119. package/dist/types/decorators/elementDefine.d.ts +0 -14
  120. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  121. package/dist/types/decorators/emitCustomEvent.d.ts +28 -4
  122. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  123. package/dist/types/decorators/eventMedia.d.ts +25 -0
  124. package/dist/types/decorators/eventMedia.d.ts.map +1 -0
  125. package/dist/types/decorators/index.d.ts +6 -1
  126. package/dist/types/decorators/index.d.ts.map +1 -1
  127. package/dist/types/decorators/intersectionObserver.d.ts +58 -0
  128. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -0
  129. package/dist/types/decorators/mutationObserver.d.ts +44 -25
  130. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  131. package/dist/types/decorators/parameter.d.ts +35 -0
  132. package/dist/types/decorators/parameter.d.ts.map +1 -0
  133. package/dist/types/decorators/query.d.ts +57 -14
  134. package/dist/types/decorators/query.d.ts.map +1 -1
  135. package/dist/types/decorators/requestAnimationFrame.d.ts +47 -0
  136. package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -0
  137. package/dist/types/decorators/resizeObserver.d.ts +43 -23
  138. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  139. package/dist/types/decorators/setInterval.d.ts +41 -0
  140. package/dist/types/decorators/setInterval.d.ts.map +1 -0
  141. package/dist/types/decorators/setTimeout.d.ts +41 -0
  142. package/dist/types/decorators/setTimeout.d.ts.map +1 -0
  143. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +7 -1
  144. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  145. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +6 -0
  146. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  147. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  148. package/dist/types/types/index.d.ts +104 -0
  149. package/dist/types/types/index.d.ts.map +1 -1
  150. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +4961 -1628
  151. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  152. package/package.json +7 -5
  153. package/src/config/config.ts +1 -1
  154. package/src/decorators/addEventListener.ts +1446 -34
  155. package/src/decorators/applyAttribute.ts +60 -36
  156. package/src/decorators/applyClass.ts +86 -26
  157. package/src/decorators/applyNode.ts +124 -36
  158. package/src/decorators/applyProperty.ts +172 -40
  159. package/src/decorators/applySlot.ts +6 -5
  160. package/src/decorators/applyStyle.ts +74 -17
  161. package/src/decorators/changedAttribute.ts +76 -15
  162. package/src/decorators/elementDefine.ts +310 -582
  163. package/src/decorators/emitCustomEvent.ts +73 -5
  164. package/src/decorators/eventMedia.ts +78 -0
  165. package/src/decorators/index.ts +6 -1
  166. package/src/decorators/intersectionObserver.ts +275 -0
  167. package/src/decorators/mutationObserver.ts +282 -89
  168. package/src/decorators/parameter.ts +81 -0
  169. package/src/decorators/query.ts +168 -126
  170. package/src/decorators/requestAnimationFrame.ts +158 -0
  171. package/src/decorators/resizeObserver.ts +211 -89
  172. package/src/decorators/setInterval.ts +136 -0
  173. package/src/decorators/setTimeout.ts +139 -0
  174. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +17 -0
  175. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +19 -0
  176. package/src/elements/SwcAppMixin.ts +20 -5
  177. package/src/types/index.ts +141 -0
  178. package/src/types/window.d.ts +2 -18
  179. package/dist/cjs/decorators/queryAll.js +0 -181
  180. package/dist/cjs/decorators/queryAll.js.map +0 -7
  181. package/dist/cjs/examples/RxJSOperatorsExample.js +0 -285
  182. package/dist/cjs/examples/RxJSOperatorsExample.js.map +0 -7
  183. package/dist/esm/decorators/queryAll.js +0 -162
  184. package/dist/esm/decorators/queryAll.js.map +0 -7
  185. package/dist/esm/examples/RxJSOperatorsExample.js +0 -266
  186. package/dist/esm/examples/RxJSOperatorsExample.js.map +0 -7
  187. package/dist/types/decorators/queryAll.d.ts +0 -22
  188. package/dist/types/decorators/queryAll.d.ts.map +0 -1
  189. package/dist/types/examples/RxJSOperatorsExample.d.ts +0 -94
  190. package/dist/types/examples/RxJSOperatorsExample.d.ts.map +0 -1
  191. package/src/decorators/queryAll.ts +0 -186
  192. package/src/examples/RxJSOperatorsExample.ts +0 -279
@@ -1,6 +1,6 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { ensureInit, getElementConfig } from './elementDefine';
3
- import {SpecialSelector, SwcQueryOptions, HelperHostSet, SwcRootType} from '../types';
3
+ import {SpecialSelector, SwcQueryOptions, SwcFnSelector, SwcSelector, HelperHostSet, SwcRootType} from '../types';
4
4
  import { SwcUtils} from "../utils/Utils";
5
5
  import {findAllStateMetadata} from "./state";
6
6
  import {ElementApply} from "@dooboostore/core-web";
@@ -15,28 +15,26 @@ import {ElementApply} from "@dooboostore/core-web";
15
15
  */
16
16
  export type ApplyNodePosition = 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd' | 'replace' | 'replaceChildren' | 'innerHtml' | 'innerText' | 'remove' | 'clearChildren';
17
17
 
18
- export type ApplyNodeSelector = string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null);
18
+ export type ApplyNodeFnSelector = SwcFnSelector;
19
+ export type ApplyNodeSelector = SwcSelector;
19
20
 
20
- export interface ApplyNodeOptions {
21
+ // 공통 옵션 — root 없음
22
+ export interface ApplyNodeBaseOptions {
21
23
  position?: ApplyNodePosition;
22
- root?: SwcRootType;
23
- /**
24
- * Filter function to determine whether to perform DOM operation.
25
- * If it returns false, the operation is skipped.
26
- */
27
24
  filter?: (target: HTMLElement | ShadowRoot, newValue: any, meta: { currentThis: any, helper: HelperHostSet }) => boolean;
28
- /**
29
- * Optional loading content to display while an async method is executing.
30
- */
31
25
  fallback?: (helper: HelperHostSet) => any;
32
- /**
33
- * Custom key to extract value from return object.
34
- * If not provided, uses APPLY_NODE_METADATA_KEY by default.
35
- * Useful when multiple @applyNode decorators are on the same method.
36
- */
37
26
  valueKey?: symbol | string;
38
27
  }
39
28
 
29
+ // 문자열 셀렉터 전용 — root 허용
30
+ export type ApplyNodeQueryOptions = ApplyNodeBaseOptions & { root?: SwcRootType };
31
+ // 함수 셀렉터 전용 — root 금지
32
+ export type ApplyNodeNonQueryOptions = ApplyNodeBaseOptions;
33
+ export type ApplyNodeOptions = ApplyNodeQueryOptions;
34
+
35
+ // 셀렉터 종류에 따라 옵션 타입 분기
36
+ export type ApplyNodeOptionsOf<S extends ApplyNodeSelector> = S extends string ? ApplyNodeQueryOptions : ApplyNodeNonQueryOptions;
37
+
40
38
  export interface ApplyNodeMetadata {
41
39
  propertyKey: string | symbol;
42
40
  selector: ApplyNodeSelector;
@@ -141,8 +139,9 @@ const applyToDom = (currentThis: any, targetEl: HTMLElement, res: Node | string,
141
139
  * - applyNode(selector, options) - Apply to specific selector
142
140
  * - applyNode(options) - Apply to $this (current element)
143
141
  */
144
- export function applyNode(selector: ApplyNodeSelector, options?: ApplyNodeOptions): MethodDecorator;
145
- export function applyNode(options: ApplyNodeOptions): MethodDecorator;
142
+ export function applyNode(selector: string, options?: ApplyNodeQueryOptions): MethodDecorator;
143
+ export function applyNode(selector: ApplyNodeFnSelector, options?: ApplyNodeNonQueryOptions): MethodDecorator;
144
+ export function applyNode(options: ApplyNodeQueryOptions): MethodDecorator;
146
145
  export function applyNode(selectorOrOptions: ApplyNodeSelector | ApplyNodeOptions, maybeOptions?: ApplyNodeOptions): MethodDecorator {
147
146
  // Determine selector and options based on overload
148
147
  let selector: ApplyNodeSelector;
@@ -278,8 +277,13 @@ export function applyNode(selectorOrOptions: ApplyNodeSelector | ApplyNodeOption
278
277
  * - replaceChildrenNode(options) - Replace children of $this (current element)
279
278
  * - @replaceChildrenNode - Bare decorator, replaces children of $this
280
279
  */
281
- export function replaceChildren(selector: ApplyNodeSelector, options?: Omit<ApplyNodeOptions, 'position'>): MethodDecorator;
282
- export function replaceChildren(options: Omit<ApplyNodeOptions, 'position'>): MethodDecorator;
280
+ export type ApplyNodeQueryOptionsNoPos = Omit<ApplyNodeQueryOptions, 'position'>;
281
+ export type ApplyNodeNonQueryOptionsNoPos = Omit<ApplyNodeNonQueryOptions, 'position'>;
282
+ export type ApplyNodeOptionsOfNoPos<S extends ApplyNodeSelector> = S extends string ? ApplyNodeQueryOptionsNoPos : ApplyNodeNonQueryOptionsNoPos;
283
+
284
+ export function replaceChildren(selector: string, options?: ApplyNodeQueryOptionsNoPos): MethodDecorator;
285
+ export function replaceChildren(selector: ApplyNodeFnSelector, options?: ApplyNodeNonQueryOptionsNoPos): MethodDecorator;
286
+ export function replaceChildren(options: ApplyNodeQueryOptionsNoPos): MethodDecorator;
283
287
  export function replaceChildren(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
284
288
  export function replaceChildren(selectorOrOptions?: ApplyNodeSelector | Omit<ApplyNodeOptions, 'position'> | Object, maybeOptions?: Omit<ApplyNodeOptions, 'position'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | PropertyDescriptor | void {
285
289
  // Bare decorator usage: @replaceChildrenNode
@@ -288,7 +292,7 @@ export function replaceChildren(selectorOrOptions?: ApplyNodeSelector | Omit<App
288
292
  }
289
293
 
290
294
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
291
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'replaceChildren'});
295
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'replaceChildren'});
292
296
  }
293
297
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'replaceChildren'});
294
298
  }
@@ -311,7 +315,7 @@ export function clearChildrenNode(selectorOrOptions?: ApplyNodeSelector | Omit<A
311
315
  }
312
316
 
313
317
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
314
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'clearChildren'});
318
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'clearChildren'});
315
319
  }
316
320
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'clearChildren'});
317
321
  }
@@ -337,7 +341,7 @@ export function innerHtml(selectorOrOptions?: ApplyNodeSelector | Omit<ApplyNode
337
341
  }
338
342
 
339
343
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
340
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerHtml'});
344
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerHtml'});
341
345
  }
342
346
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerHtml'});
343
347
  }
@@ -363,7 +367,7 @@ export function innerHtmlLight(selectorOrOptions?: ApplyNodeSelector | Omit<Appl
363
367
  }
364
368
 
365
369
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
366
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'light'});
370
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'light'});
367
371
  }
368
372
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'light'});
369
373
  }
@@ -387,7 +391,7 @@ export function innerHtmlShadow(selectorOrOptions?: ApplyNodeSelector | Omit<App
387
391
  }
388
392
 
389
393
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
390
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'shadow'});
394
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'shadow'});
391
395
  }
392
396
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerHtml', root: 'shadow'});
393
397
  }
@@ -411,7 +415,7 @@ export function innerText(selectorOrOptions?: ApplyNodeSelector | Omit<ApplyNode
411
415
  }
412
416
 
413
417
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
414
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerText'});
418
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerText'});
415
419
  }
416
420
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'innerText'});
417
421
  }
@@ -435,7 +439,7 @@ export function innerTextLight(selectorOrOptions?: ApplyNodeSelector | Omit<Appl
435
439
  }
436
440
 
437
441
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
438
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'light'});
442
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'light'});
439
443
  }
440
444
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'light'});
441
445
  }
@@ -458,7 +462,7 @@ export function innerTextShadow(selectorOrOptions?: ApplyNodeSelector | Omit<App
458
462
  }
459
463
 
460
464
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
461
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'shadow'});
465
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'shadow'});
462
466
  }
463
467
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'innerText', root: 'shadow'});
464
468
  }
@@ -481,7 +485,7 @@ export function insertBeforeEnd(selectorOrOptions?: ApplyNodeSelector | Omit<App
481
485
  }
482
486
 
483
487
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
484
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'beforeEnd'});
488
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'beforeEnd'});
485
489
  }
486
490
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'beforeEnd'});
487
491
  }
@@ -505,7 +509,7 @@ export function insertBeforeEndLight(selectorOrOptions?: ApplyNodeSelector | Omi
505
509
  }
506
510
 
507
511
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
508
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'light'});
512
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'light'});
509
513
  }
510
514
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'light'});
511
515
  }
@@ -529,7 +533,7 @@ export function insertBeforeEndShadow(selectorOrOptions?: ApplyNodeSelector | Om
529
533
  }
530
534
 
531
535
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
532
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'shadow'});
536
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'shadow'});
533
537
  }
534
538
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'beforeEnd', root: 'shadow'});
535
539
  }
@@ -553,7 +557,7 @@ export function insertAfterBegin(selectorOrOptions?: ApplyNodeSelector | Omit<Ap
553
557
  }
554
558
 
555
559
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
556
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'afterBegin'});
560
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'afterBegin'});
557
561
  }
558
562
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'afterBegin'});
559
563
  }
@@ -577,7 +581,7 @@ export function insertAfterBeginLight(selectorOrOptions?: ApplyNodeSelector | Om
577
581
  }
578
582
 
579
583
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
580
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'afterBegin', root: 'light'});
584
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'afterBegin', root: 'light'});
581
585
  }
582
586
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'afterBegin', root: 'light'});
583
587
  }
@@ -601,7 +605,7 @@ export function replaceChildrenLight(selectorOrOptions?: ApplyNodeSelector | Omi
601
605
  }
602
606
 
603
607
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
604
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'replaceChildren', root: 'light'});
608
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'replaceChildren', root: 'light'});
605
609
  }
606
610
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'replaceChildren', root: 'light'});
607
611
  }
@@ -624,7 +628,7 @@ export function clearChildrenLight(selectorOrOptions?: ApplyNodeSelector | Omit<
624
628
  }
625
629
 
626
630
  if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
627
- return applyNode(selectorOrOptions as ApplyNodeSelector, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'clearChildren', root: 'light'});
631
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'clearChildren', root: 'light'});
628
632
  }
629
633
  return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position' | 'root'>, position: 'clearChildren', root: 'light'});
630
634
  }
@@ -632,6 +636,38 @@ export function clearChildrenLight(selectorOrOptions?: ApplyNodeSelector | Omit<
632
636
 
633
637
 
634
638
 
639
+ // ─── Aliases ───
640
+ export const apply = applyNode;
641
+ export const node = applyNode;
642
+
643
+ // ─── 편의 헬퍼 (selector/root 생략) ───
644
+
645
+ export function applyThis(options?: ApplyNodeQueryOptions): MethodDecorator;
646
+ export function applyThis(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
647
+ export function applyThis(optionsOrTarget?: ApplyNodeQueryOptions | Object, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | PropertyDescriptor | void {
648
+ if ((typeof propertyKey === 'string' || typeof propertyKey === 'symbol') && descriptor !== undefined) {
649
+ return (applyNode('$this', {}) as any)(optionsOrTarget, propertyKey, descriptor);
650
+ }
651
+ return applyNode('$this', optionsOrTarget as ApplyNodeQueryOptions);
652
+ }
653
+ export function applyAppHost(options?: ApplyNodeQueryOptions): MethodDecorator;
654
+ export function applyAppHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
655
+ export function applyAppHost(optionsOrTarget?: ApplyNodeQueryOptions | Object, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | PropertyDescriptor | void {
656
+ if ((typeof propertyKey === 'string' || typeof propertyKey === 'symbol') && descriptor !== undefined) {
657
+ return (applyNode('$appHost', {}) as any)(optionsOrTarget, propertyKey, descriptor);
658
+ }
659
+ return applyNode('$appHost', optionsOrTarget as ApplyNodeQueryOptions);
660
+ }
661
+ export function applyLight(selector: string, options?: Omit<ApplyNodeQueryOptions, 'root'>): MethodDecorator {
662
+ return applyNode(selector, {...options ?? {}, root: 'light'});
663
+ }
664
+ export function applyShadow(selector: string, options?: Omit<ApplyNodeQueryOptions, 'root'>): MethodDecorator {
665
+ return applyNode(selector, {...options ?? {}, root: 'shadow'});
666
+ }
667
+ export function applyAll(selector: string, options?: Omit<ApplyNodeQueryOptions, 'root'>): MethodDecorator {
668
+ return applyNode(selector, {...options ?? {}, root: 'all'});
669
+ }
670
+
635
671
  export const findAllApplyNodeMetadata = (target: any): Map<string | symbol, ApplyNodeMetadata> => {
636
672
  const result = new Map<string | symbol, ApplyNodeMetadata>();
637
673
  const maps = ReflectUtils.findAllMetadata<Map<string | symbol, ApplyNodeMetadata>>(APPLY_NODE_METADATA_KEY, target);
@@ -641,4 +677,56 @@ export const findAllApplyNodeMetadata = (target: any): Map<string | symbol, Appl
641
677
  }
642
678
  });
643
679
  return result;
644
- };
680
+ };
681
+ // ─── filter 유틸 (applyNode/replace*/innerHtml* options.filter용) ───
682
+ // filter는 true 반환 시 적용, false 반환 시 스킵.
683
+
684
+ const filterScopeOf = (target: HTMLElement | ShadowRoot): Element | null => {
685
+ if (target && typeof (target as HTMLElement).querySelector === 'function') {
686
+ return target as unknown as Element;
687
+ }
688
+ const host = (target as ShadowRoot)?.host as unknown as Element | undefined;
689
+ return host && typeof host.querySelector === 'function' ? host : null;
690
+ };
691
+
692
+ const tagNameOf = (node: any): string | null => {
693
+ const tag = node?.tagName;
694
+ return typeof tag === 'string' ? tag.toLowerCase() : null;
695
+ };
696
+
697
+ // 새 노드와 같은 태그가 target 안에 이미 있으면 스킵 (SSR adopting용).
698
+ export const skipIfSameTagPresent = (target: HTMLElement | ShadowRoot, newValue: any): boolean => {
699
+ const nodes = (Array.isArray(newValue) ? newValue : [newValue]).filter((n) => tagNameOf(n) !== null);
700
+ if (nodes.length === 0) return true;
701
+ const scope = filterScopeOf(target);
702
+ if (!scope) return true;
703
+ return !nodes.some((n) => scope.querySelector(tagNameOf(n)!));
704
+ };
705
+
706
+ // 지정 selector가 target 안에 이미 있으면 스킵 (같은 path 쿼리 변경 시 페이지 재생성 방지용).
707
+ // 사용: @innerHtmlLight({ filter: skipIfExists('center-math-page') })
708
+ export const skipIfExists = (selector: string) =>
709
+ (target: HTMLElement | ShadowRoot): boolean => {
710
+ const scope = filterScopeOf(target);
711
+ if (!scope) return true;
712
+ return !scope.querySelector(selector);
713
+ };
714
+
715
+ // 새 값이 비어있으면 스킵 (null/''/빈 배열).
716
+ export const skipIfEmpty = (_target: HTMLElement | ShadowRoot, newValue: any): boolean => {
717
+ if (newValue === null || newValue === undefined || newValue === false) return false;
718
+ if (typeof newValue === 'string') return newValue.trim().length > 0;
719
+ if (Array.isArray(newValue)) return newValue.length > 0;
720
+ return true;
721
+ };
722
+
723
+ // 텍스트가 달라질 때만 적용 (폴링 갱신용).
724
+ export const applyIfChanged = (target: HTMLElement | ShadowRoot, newValue: any): boolean => {
725
+ const textOf = (v: any): string => {
726
+ if (typeof v === 'string') return v;
727
+ if (Array.isArray(v)) return v.map(textOf).join('');
728
+ return typeof v?.textContent === 'string' ? v.textContent : '';
729
+ };
730
+ const current = typeof (target as HTMLElement)?.textContent === 'string' ? (target as HTMLElement).textContent! : '';
731
+ return current !== textOf(newValue);
732
+ };
@@ -1,40 +1,31 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { ensureInit, getElementConfig } from './elementDefine';
3
3
  import { SwcUtils } from '../utils/Utils';
4
- import { SwcQueryOptions, HelperHostSet } from '../types';
4
+ import { SwcQueryOptions, HelperHostSet, SwcFnSelector, SwcSelector } from '../types';
5
5
 
6
- export interface PropertyOptions extends SwcQueryOptions {
6
+ // 공통 옵션 — root 없음
7
+ export interface PropertyBaseOptions {
7
8
  name?: string | symbol;
8
9
  filter?: (target: HTMLElement, value: any, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
9
- /**
10
- * Custom key to extract value from return object.
11
- * If not provided, uses PROPERTY_METADATA_KEY by default.
12
- * Useful when multiple @setProperty decorators are on the same method.
13
- *
14
- * Example:
15
- * @setProperty('selector1', { valueKey: 'prop1' })
16
- * @setProperty('selector2', { valueKey: 'prop2' })
17
- * myMethod() {
18
- * return {
19
- * prop1: 'value1',
20
- * prop2: 'value2'
21
- * };
22
- * }
23
- *
24
- * Or with symbols:
25
- * @setProperty('selector1', { valueKey: Symbol.for('prop1') })
26
- * @setProperty('selector2', { valueKey: Symbol.for('prop2') })
27
- * myMethod() {
28
- * return {
29
- * [Symbol.for('prop1')]: 'value1',
30
- * [Symbol.for('prop2')]: 'value2'
31
- * };
32
- * }
33
- */
34
10
  valueKey?: symbol | string;
11
+ /** 읽기 방식: 'get' 타깃 프로퍼티 읽기 (기본), 'call' 타깃 호출 후 리턴 사용 */
12
+ getType?: 'get' | 'call';
13
+ /** 쓰기 방식: 'set' 타깃 프로퍼티 대입 (기본), 'call' 타깃 호출 (배열이면 spread) */
14
+ setType?: 'set' | 'call';
35
15
  }
36
16
 
37
- export type PropertySelector = string | ((currentThis: any, helper: HelperHostSet) => NodeList | Element | Element[] | null);
17
+ // 문자열 셀렉터 전용 — root 허용
18
+ export type PropertyQueryOptions = PropertyBaseOptions & SwcQueryOptions;
19
+ // 함수 셀렉터 전용 — root 금지
20
+ export type PropertyNonQueryOptions = PropertyBaseOptions;
21
+ // 내부 저장/해석용 — root optional이라 두 종류 모두 저장 가능
22
+ export type PropertyOptions = PropertyQueryOptions;
23
+
24
+ export type PropertyFnSelector = SwcFnSelector;
25
+ export type PropertySelector = SwcSelector;
26
+
27
+ // 셀렉터 종류에 따라 옵션 타입 분기
28
+ export type PropertyOptionsOf<S extends PropertySelector> = S extends string ? PropertyQueryOptions : PropertyNonQueryOptions;
38
29
 
39
30
  export interface PropertyMetadata {
40
31
  propertyKey: string | symbol;
@@ -62,7 +53,7 @@ export const resolvePropertyTargets = (inst: any, selector: PropertySelector, op
62
53
  const results: any[] = [];
63
54
 
64
55
  // Resolve selector if it's a function
65
- let resolvedSelector: string | Element | NodeList | Element[] | null = selector as any;
56
+ let resolvedSelector: string | Node | Element | NodeList | Element[] | null = selector as any;
66
57
  if (typeof selector === 'function') {
67
58
  const hostSet = SwcUtils.getHelperAndHostSet(currentWin, inst);
68
59
  resolvedSelector = selector(inst, hostSet);
@@ -146,9 +137,9 @@ export const resolvePropertyTargets = (inst: any, selector: PropertySelector, op
146
137
  * - @applyProperty((this, helper) => 'selector', 'propertyName') - Function-based selector
147
138
  * - Return null/undefined to skip setting
148
139
  */
149
- export function applyProperty(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
150
- export function applyProperty(selector: PropertySelector, options?: PropertyOptions): MethodDecorator & PropertyDecorator;
151
- export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator & PropertyDecorator {
140
+ export function applyProperty<S extends PropertySelector>(selector: S, targetPropertyKey: string | symbol, options?: PropertyOptionsOf<S>): MethodDecorator & PropertyDecorator;
141
+ export function applyProperty<S extends PropertySelector>(selector: S, options?: PropertyOptionsOf<S>): MethodDecorator & PropertyDecorator;
142
+ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOptions?: string | symbol | PropertyOptions, options?: PropertyOptions): MethodDecorator {
152
143
  return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
153
144
  // ensureInit(target as any);
154
145
 
@@ -186,7 +177,7 @@ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOpt
186
177
  type: metaType
187
178
  });
188
179
 
189
- // Helper: apply resolved value to targets
180
+ // Helper: apply resolved value to targets (setType 'call'이면 타깃 호출 — 배열은 spread)
190
181
  const applyValueToTargets = (inst: any, resolvedValue: any) => {
191
182
  if (resolvedValue === undefined) return resolvedValue;
192
183
 
@@ -202,6 +193,12 @@ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOpt
202
193
  }
203
194
 
204
195
  const resolvedRes = typeof resolvedValue === 'function' ? (resolvedValue as any)(targetEl, hostSet) : resolvedValue;
196
+ if (finalOptions.setType === 'call') {
197
+ if (typeof (targetEl as any)[targetPropertyKey] !== 'function') return;
198
+ if (Array.isArray(resolvedRes)) (targetEl as any)[targetPropertyKey].apply(targetEl, resolvedRes);
199
+ else (targetEl as any)[targetPropertyKey].call(targetEl, resolvedRes);
200
+ return;
201
+ }
205
202
  (targetEl as any)[targetPropertyKey] = resolvedRes;
206
203
  });
207
204
 
@@ -274,7 +271,12 @@ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOpt
274
271
  return true;
275
272
  });
276
273
 
277
- const values = filtered.map(el => (el as any)[targetPropertyKey]);
274
+ const values = filtered.map(el => {
275
+ const raw = (el as any)[targetPropertyKey];
276
+ // getType 'call'이면 타깃 호출 후 리턴 사용
277
+ if (finalOptions.getType === 'call' && typeof raw === 'function') return raw.call(el);
278
+ return raw;
279
+ });
278
280
  return values.length === 1 ? values[0] : values;
279
281
  },
280
282
  set(this: any, value: any) {
@@ -301,19 +303,28 @@ export function applyProperty(selector: PropertySelector, targetPropertyKeyOrOpt
301
303
  *
302
304
  * Note: This decorator is for FIELDS ONLY. For methods, use @setProperty.
303
305
  */
306
+ export function property(selector: string, targetPropertyKey: string | symbol, options?: PropertyQueryOptions): PropertyDecorator;
307
+ export function property(selector: PropertyFnSelector, targetPropertyKey: string | symbol, options?: PropertyNonQueryOptions): PropertyDecorator;
308
+ export function property(selector: string, options?: PropertyQueryOptions): PropertyDecorator;
309
+ export function property(selector: PropertyFnSelector, options?: PropertyNonQueryOptions): PropertyDecorator;
304
310
  export function property(target: Object, propertyKey: string | symbol): void;
305
311
  export function property(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
306
- export function property(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): PropertyDecorator;
307
- export function property(selector: PropertySelector, options?: PropertyOptions): PropertyDecorator;
308
312
  export function property(selectorOrTarget?: PropertySelector | Object, targetPropertyKeyOrOptions?: any, optionsOrDescriptor?: any): any {
309
- // Bare decorator: @property
310
- if (optionsOrDescriptor !== undefined && (typeof targetPropertyKeyOrOptions === 'string' || typeof targetPropertyKeyOrOptions === 'symbol')) {
313
+ // Bare decorator direct invocation: @property on field/method passes (target, key[, descriptor]).
314
+ // NOTE: (selector-string, key, options) factory form must NOT enter here — target is never string/function.
315
+ if (optionsOrDescriptor !== undefined
316
+ && typeof selectorOrTarget !== 'string' && typeof selectorOrTarget !== 'function'
317
+ && (typeof targetPropertyKeyOrOptions === 'string' || typeof targetPropertyKeyOrOptions === 'symbol')) {
311
318
  return applyProperty('$this', undefined as any, {})(selectorOrTarget as Object, targetPropertyKeyOrOptions, optionsOrDescriptor as PropertyDescriptor);
312
319
  }
313
320
  // With selector
314
321
  if (typeof selectorOrTarget === 'string') {
315
322
  return applyProperty(selectorOrTarget, targetPropertyKeyOrOptions as any, optionsOrDescriptor as PropertyOptions);
316
323
  }
324
+ // Function selector
325
+ if (typeof selectorOrTarget === 'function') {
326
+ return applyProperty(selectorOrTarget as PropertyFnSelector, targetPropertyKeyOrOptions as any, optionsOrDescriptor as PropertyOptions);
327
+ }
317
328
  // Without selector (defaults to $this)
318
329
  return applyProperty('$this', undefined as any, selectorOrTarget as PropertyOptions);
319
330
  }
@@ -336,17 +347,69 @@ export function property(selectorOrTarget?: PropertySelector | Object, targetPro
336
347
  * return true;
337
348
  * }
338
349
  */
339
- export function setProperty(selector: PropertySelector, targetPropertyKey: string | symbol, options?: PropertyOptions): MethodDecorator;
340
- export function setProperty(selector: PropertySelector, options?: PropertyOptions): MethodDecorator;
350
+ export function setProperty(selector: string, targetPropertyKey: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
351
+ export function setProperty(selector: PropertyFnSelector, targetPropertyKey: string | symbol, options?: PropertyNonQueryOptions): MethodDecorator;
352
+ export function setProperty(selector: string, options?: PropertyQueryOptions): MethodDecorator;
353
+ export function setProperty(selector: PropertyFnSelector, options?: PropertyNonQueryOptions): MethodDecorator;
341
354
  export function setProperty(selectorOrOptions?: PropertySelector | PropertyOptions, targetPropertyKeyOrOptions?: any, optionsOrUndefined?: PropertyOptions): MethodDecorator {
342
355
  // With selector
343
356
  if (typeof selectorOrOptions === 'string') {
344
357
  return applyProperty(selectorOrOptions, targetPropertyKeyOrOptions as any, optionsOrUndefined as PropertyOptions) as MethodDecorator;
345
358
  }
359
+ // Function selector
360
+ if (typeof selectorOrOptions === 'function') {
361
+ return applyProperty(selectorOrOptions as PropertyFnSelector, targetPropertyKeyOrOptions as any, optionsOrUndefined as PropertyOptions) as MethodDecorator;
362
+ }
346
363
  // Without selector (defaults to $this)
347
364
  return applyProperty('$this', undefined as any, selectorOrOptions as PropertyOptions) as MethodDecorator;
348
365
  }
349
366
 
367
+ /**
368
+ * @callProperty - Method decorator for calling a method on matched elements.
369
+ * - @callProperty('selector', 'methodName') - 메서드 리턴값으로 타깃 메서드 호출
370
+ * - @callProperty('selector') - 메서드 이름과 같은 타깃 메서드 호출
371
+ * - 리턴값이 배열이면 spread 인자로 호출, 아니면 단일 인자로 호출
372
+ *
373
+ * Example:
374
+ * @event('#popup', 'open-request')
375
+ * @callProperty('#popup', 'show')
376
+ * onPopupOpen() {
377
+ * return [this.rows]; // popup.show(this.rows)
378
+ * }
379
+ */
380
+ export function callProperty(selector: string, targetMethodKey?: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
381
+ export function callProperty(selector: PropertyFnSelector, targetMethodKey?: string | symbol, options?: PropertyNonQueryOptions): MethodDecorator;
382
+ export function callProperty(selector: string, options?: PropertyQueryOptions): MethodDecorator;
383
+ export function callProperty(selectorOrTarget?: PropertySelector | PropertyOptions, targetMethodKeyOrOptions?: any, optionsOrUndefined?: PropertyOptions): MethodDecorator {
384
+ // setType 'call' 위임 — 메서드 리턴값을 타깃 메서드 호출로 전달 (배열이면 spread)
385
+ if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
386
+ if (typeof targetMethodKeyOrOptions === 'string' || typeof targetMethodKeyOrOptions === 'symbol') {
387
+ return applyProperty(selectorOrTarget as any, targetMethodKeyOrOptions, { ...optionsOrUndefined ?? {}, setType: 'call' }) as MethodDecorator;
388
+ }
389
+ return applyProperty(selectorOrTarget as any, { ...optionsOrUndefined ?? targetMethodKeyOrOptions ?? {}, setType: 'call' }) as MethodDecorator;
390
+ }
391
+ return applyProperty('$this', undefined as any, { ...selectorOrTarget ?? {}, setType: 'call' }) as MethodDecorator;
392
+ }
393
+ export function callPropertyLight(selector: string, targetMethodKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator;
394
+ export function callPropertyLight(selector: string, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator;
395
+ export function callPropertyLight(selector: string, targetMethodKeyOrOptions?: any, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
396
+ if (targetMethodKeyOrOptions != null && typeof targetMethodKeyOrOptions !== 'string' && typeof targetMethodKeyOrOptions !== 'symbol') {
397
+ return callProperty(selector, undefined, { ...targetMethodKeyOrOptions ?? {}, root: 'light' });
398
+ }
399
+ return callProperty(selector, targetMethodKeyOrOptions as any, { ...options ?? {}, root: 'light' });
400
+ }
401
+ export function callPropertyShadow(selector: string, targetMethodKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator;
402
+ export function callPropertyShadow(selector: string, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator;
403
+ export function callPropertyShadow(selector: string, targetMethodKeyOrOptions?: any, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
404
+ if (targetMethodKeyOrOptions != null && typeof targetMethodKeyOrOptions !== 'string' && typeof targetMethodKeyOrOptions !== 'symbol') {
405
+ return callProperty(selector, undefined, { ...targetMethodKeyOrOptions ?? {}, root: 'shadow' });
406
+ }
407
+ return callProperty(selector, targetMethodKeyOrOptions as any, { ...options ?? {}, root: 'shadow' });
408
+ }
409
+ export function callPropertyAll(selector: string, targetMethodKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
410
+ return callProperty(selector, targetMethodKey as any, { ...options ?? {}, root: 'all' });
411
+ }
412
+
350
413
  // ============================================
351
414
  // Metadata Helpers
352
415
  // ============================================
@@ -365,5 +428,74 @@ export const findAllPropertyApplyMetadata = (target: any): Map<string | symbol,
365
428
  return result;
366
429
  };
367
430
 
431
+ // ─── Aliases ───
432
+ // property(필드) / setProperty(메서드)와 구분되는 일반 데코레이터 단축명
433
+ export const prop = applyProperty;
434
+
435
+ // ─── 편의 헬퍼 (selector/root 생략) ───
436
+
437
+ const dispatchPropConvenience = (
438
+ selector: '$this' | '$appHost' | '$window' | '$document',
439
+ targetPropertyKeyOrTarget?: string | symbol | Object,
440
+ optionsOrPropertyKey?: PropertyQueryOptions | string | symbol,
441
+ descriptor?: PropertyDescriptor
442
+ ): any => {
443
+ if ((typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol') && descriptor !== undefined) {
444
+ return (applyProperty(selector, undefined as any, {}) as any)(targetPropertyKeyOrTarget, optionsOrPropertyKey, descriptor);
445
+ }
446
+ return applyProperty(selector, targetPropertyKeyOrTarget as any, optionsOrPropertyKey as PropertyQueryOptions);
447
+ };
448
+
449
+ export function propThis(targetPropertyKey?: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
450
+ export function propThis(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
451
+ export function propThis(targetPropertyKeyOrTarget?: string | symbol | Object, optionsOrPropertyKey?: PropertyQueryOptions | string | symbol, descriptor?: PropertyDescriptor): any {
452
+ return dispatchPropConvenience('$this', targetPropertyKeyOrTarget, optionsOrPropertyKey, descriptor);
453
+ }
454
+ export function propAppHost(targetPropertyKey?: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
455
+ export function propAppHost(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
456
+ export function propAppHost(targetPropertyKeyOrTarget?: string | symbol | Object, optionsOrPropertyKey?: PropertyQueryOptions | string | symbol, descriptor?: PropertyDescriptor): any {
457
+ return dispatchPropConvenience('$appHost', targetPropertyKeyOrTarget, optionsOrPropertyKey, descriptor);
458
+ }
459
+ export function propWindow(targetPropertyKey?: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
460
+ export function propWindow(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
461
+ export function propWindow(targetPropertyKeyOrTarget?: string | symbol | Object, optionsOrPropertyKey?: PropertyQueryOptions | string | symbol, descriptor?: PropertyDescriptor): any {
462
+ return dispatchPropConvenience('$window', targetPropertyKeyOrTarget, optionsOrPropertyKey, descriptor);
463
+ }
464
+ export function propDocument(targetPropertyKey?: string | symbol, options?: PropertyQueryOptions): MethodDecorator;
465
+ export function propDocument(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
466
+ export function propDocument(targetPropertyKeyOrTarget?: string | symbol | Object, optionsOrPropertyKey?: PropertyQueryOptions | string | symbol, descriptor?: PropertyDescriptor): any {
467
+ return dispatchPropConvenience('$document', targetPropertyKeyOrTarget, optionsOrPropertyKey, descriptor);
468
+ }
469
+ export function propLight(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
470
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'light'});
471
+ }
472
+ export function propShadow(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
473
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'shadow'});
474
+ }
475
+ export function propAll(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
476
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'all'});
477
+ }
478
+
479
+ // ─── setProperty root 별칭 (메서드 리턴값 → 타깃 프로퍼티) ───
480
+ export function setPropertyLight(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
481
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'light'});
482
+ }
483
+ export function setPropertyShadow(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
484
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'shadow'});
485
+ }
486
+ export function setPropertyAll(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): MethodDecorator {
487
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'all'});
488
+ }
489
+
490
+ // ─── property root 별칭 (필드 프록시) ───
491
+ export function propertyLight(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): PropertyDecorator {
492
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'light'});
493
+ }
494
+ export function propertyShadow(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): PropertyDecorator {
495
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'shadow'});
496
+ }
497
+ export function propertyAll(selector: string, targetPropertyKey?: string | symbol, options?: Omit<PropertyQueryOptions, 'root'>): PropertyDecorator {
498
+ return applyProperty(selector, targetPropertyKey, {...options ?? {}, root: 'all'});
499
+ }
368
500
 
369
501
  export default applyProperty;
@@ -73,8 +73,8 @@ export const APPLY_SLOT_METADATA_KEY = Symbol.for('simple-web-component:apply-sl
73
73
  // }
74
74
  // };
75
75
 
76
- const applyToDom = (swcId: string, id: string, pos: ApplySlotPosition, nodes: Node[]) => {
77
- const nodeSlot = new NodeSlot(this, swcId);
76
+ const applyToDom = (host: HTMLElement, swcId: string, id: string, pos: ApplySlotPosition, nodes: Node[]) => {
77
+ const nodeSlot = new NodeSlot(host, swcId);
78
78
  if (pos === 'replaceChildrenText' || pos === 'replaceChildren' || pos === 'replaceChildrenHtml') {
79
79
  nodeSlot.replaceChildren(id, ...nodes);
80
80
  } else if (pos === 'appendHtml' || pos === 'append' || pos === 'appendText') {
@@ -109,6 +109,7 @@ export function applySlot(targetId: string, opt: OptionalType<ApplySlotOptions,
109
109
  descriptor.value = function (...args: any[]) {
110
110
  ensureInit(this);
111
111
 
112
+ const host = this;
112
113
  const conf = getElementConfig(this);
113
114
  const currentWin = conf.window;
114
115
  const swcId = this._swcId;
@@ -137,7 +138,7 @@ export function applySlot(targetId: string, opt: OptionalType<ApplySlotOptions,
137
138
  const res: string | Node = options.fallback.call(this, hostSet);
138
139
  const nodes: Node[] = resToNodes(res);
139
140
  fallbackNodes.push(...nodes);
140
- applyToDom(swcId, targetId, options.position, nodes);
141
+ applyToDom(host, swcId, targetId, options.position, nodes);
141
142
  }
142
143
 
143
144
  /**
@@ -162,12 +163,12 @@ export function applySlot(targetId: string, opt: OptionalType<ApplySlotOptions,
162
163
  const extracted = extractValue(asyncRes);
163
164
  const nodes = resToNodes(extracted)
164
165
  fallbackNodes.forEach((it: any) => it.remove());
165
- applyToDom(swcId, targetId, options.position, nodes);
166
+ applyToDom(host, swcId, targetId, options.position, nodes);
166
167
  })
167
168
  } else {
168
169
  const extracted = extractValue(res);
169
170
  const nodes: Node[] = resToNodes(extracted);
170
- applyToDom(swcId, targetId, options.position, nodes);
171
+ applyToDom(host, swcId, targetId, options.position, nodes);
171
172
  }
172
173
  };
173
174
  };