@dooboostore/simple-web-component 1.0.50 → 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 (241) hide show
  1. package/README.md +735 -354
  2. package/dist/cjs/SwcAppEngine.js.map +2 -2
  3. package/dist/cjs/decorators/addEventListener.js +64 -146
  4. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  5. package/dist/cjs/decorators/applyAttribute.js +36 -48
  6. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  7. package/dist/cjs/decorators/applyClass.js +9 -12
  8. package/dist/cjs/decorators/applyClass.js.map +2 -2
  9. package/dist/cjs/decorators/applyNode.js +14 -22
  10. package/dist/cjs/decorators/applyNode.js.map +2 -2
  11. package/dist/cjs/decorators/applyProperty.js +12 -42
  12. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  13. package/dist/cjs/decorators/applySlot.js +3 -3
  14. package/dist/cjs/decorators/applySlot.js.map +2 -2
  15. package/dist/cjs/decorators/applyStyle.js +9 -12
  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 +40 -12
  20. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  21. package/dist/cjs/decorators/elementDefine.js +224 -195
  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 +36 -8
  26. package/dist/cjs/decorators/eventMedia.js.map +2 -2
  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 +5 -2
  30. package/dist/cjs/decorators/index.js.map +2 -2
  31. package/dist/cjs/decorators/intersectionObserver.js +33 -13
  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 +55 -39
  36. package/dist/cjs/decorators/mutationObserver.js.map +3 -3
  37. package/dist/cjs/decorators/parameter.js +92 -9
  38. package/dist/cjs/decorators/parameter.js.map +2 -2
  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 +7 -16
  44. package/dist/cjs/decorators/requestAnimationFrame.js.map +2 -2
  45. package/dist/cjs/decorators/resizeObserver.js +41 -17
  46. package/dist/cjs/decorators/resizeObserver.js.map +3 -3
  47. package/dist/cjs/decorators/setInterval.js +36 -25
  48. package/dist/cjs/decorators/setInterval.js.map +2 -2
  49. package/dist/cjs/decorators/setTimeout.js +36 -25
  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 -83
  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/utils/Utils.js +36 -15
  66. package/dist/cjs/utils/Utils.js.map +2 -2
  67. package/dist/esm/SwcAppEngine.js.map +2 -2
  68. package/dist/esm/decorators/addEventListener.js +64 -146
  69. package/dist/esm/decorators/addEventListener.js.map +2 -2
  70. package/dist/esm/decorators/applyAttribute.js +36 -48
  71. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  72. package/dist/esm/decorators/applyClass.js +9 -12
  73. package/dist/esm/decorators/applyClass.js.map +2 -2
  74. package/dist/esm/decorators/applyNode.js +15 -23
  75. package/dist/esm/decorators/applyNode.js.map +2 -2
  76. package/dist/esm/decorators/applyProperty.js +12 -42
  77. package/dist/esm/decorators/applyProperty.js.map +2 -2
  78. package/dist/esm/decorators/applySlot.js +3 -3
  79. package/dist/esm/decorators/applySlot.js.map +2 -2
  80. package/dist/esm/decorators/applyStyle.js +9 -12
  81. package/dist/esm/decorators/applyStyle.js.map +2 -2
  82. package/dist/esm/decorators/around.js +105 -0
  83. package/dist/esm/decorators/around.js.map +7 -0
  84. package/dist/esm/decorators/changedAttribute.js +40 -12
  85. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  86. package/dist/esm/decorators/elementDefine.js +222 -193
  87. package/dist/esm/decorators/elementDefine.js.map +3 -3
  88. package/dist/esm/decorators/emitCustomEvent.js +15 -13
  89. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  90. package/dist/esm/decorators/eventMedia.js +36 -8
  91. package/dist/esm/decorators/eventMedia.js.map +2 -2
  92. package/dist/esm/decorators/fetch.js +259 -0
  93. package/dist/esm/decorators/fetch.js.map +7 -0
  94. package/dist/esm/decorators/index.js +5 -2
  95. package/dist/esm/decorators/index.js.map +2 -2
  96. package/dist/esm/decorators/intersectionObserver.js +33 -13
  97. package/dist/esm/decorators/intersectionObserver.js.map +2 -2
  98. package/dist/esm/decorators/lifecycles.js +11 -11
  99. package/dist/esm/decorators/lifecycles.js.map +2 -2
  100. package/dist/esm/decorators/mutationObserver.js +55 -39
  101. package/dist/esm/decorators/mutationObserver.js.map +3 -3
  102. package/dist/esm/decorators/parameter.js +92 -9
  103. package/dist/esm/decorators/parameter.js.map +2 -2
  104. package/dist/esm/decorators/publishSwcAppMessage.js +2 -2
  105. package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
  106. package/dist/esm/decorators/query.js +11 -5
  107. package/dist/esm/decorators/query.js.map +2 -2
  108. package/dist/esm/decorators/requestAnimationFrame.js +8 -17
  109. package/dist/esm/decorators/requestAnimationFrame.js.map +2 -2
  110. package/dist/esm/decorators/resizeObserver.js +41 -17
  111. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  112. package/dist/esm/decorators/setInterval.js +37 -26
  113. package/dist/esm/decorators/setInterval.js.map +2 -2
  114. package/dist/esm/decorators/setTimeout.js +37 -26
  115. package/dist/esm/decorators/setTimeout.js.map +2 -2
  116. package/dist/esm/decorators/state.js +13 -10
  117. package/dist/esm/decorators/state.js.map +2 -2
  118. package/dist/esm/decorators/subscribeSwcAppMessage.js +53 -0
  119. package/dist/esm/decorators/subscribeSwcAppMessage.js.map +7 -0
  120. package/dist/esm/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +20 -16
  121. package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +7 -0
  122. package/dist/esm/decorators/swcAppRoute.js +130 -0
  123. package/dist/esm/decorators/swcAppRoute.js.map +7 -0
  124. package/dist/esm/elements/SwcApp.js +70 -0
  125. package/dist/esm/elements/SwcApp.js.map +2 -2
  126. package/dist/esm/elements/SwcAppMixin.js +258 -85
  127. package/dist/esm/elements/SwcAppMixin.js.map +3 -3
  128. package/dist/esm/types/index.js +5 -1
  129. package/dist/esm/types/index.js.map +2 -2
  130. package/dist/esm/utils/Utils.js +36 -15
  131. package/dist/esm/utils/Utils.js.map +2 -2
  132. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1886 -999
  133. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  134. package/dist/types/SwcAppEngine.d.ts +1 -0
  135. package/dist/types/SwcAppEngine.d.ts.map +1 -1
  136. package/dist/types/decorators/addEventListener.d.ts +923 -960
  137. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  138. package/dist/types/decorators/applyAttribute.d.ts +26 -38
  139. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  140. package/dist/types/decorators/applyClass.d.ts +1 -3
  141. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  142. package/dist/types/decorators/applyNode.d.ts +15 -17
  143. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  144. package/dist/types/decorators/applyProperty.d.ts +25 -45
  145. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  146. package/dist/types/decorators/applyStyle.d.ts +1 -3
  147. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  148. package/dist/types/decorators/around.d.ts +87 -0
  149. package/dist/types/decorators/around.d.ts.map +1 -0
  150. package/dist/types/decorators/changedAttribute.d.ts +21 -1
  151. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  152. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  153. package/dist/types/decorators/emitCustomEvent.d.ts +0 -1
  154. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  155. package/dist/types/decorators/eventMedia.d.ts +24 -1
  156. package/dist/types/decorators/eventMedia.d.ts.map +1 -1
  157. package/dist/types/decorators/fetch.d.ts +139 -0
  158. package/dist/types/decorators/fetch.d.ts.map +1 -0
  159. package/dist/types/decorators/index.d.ts +5 -2
  160. package/dist/types/decorators/index.d.ts.map +1 -1
  161. package/dist/types/decorators/intersectionObserver.d.ts +24 -11
  162. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
  163. package/dist/types/decorators/lifecycles.d.ts +8 -7
  164. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  165. package/dist/types/decorators/mutationObserver.d.ts +26 -13
  166. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  167. package/dist/types/decorators/parameter.d.ts +84 -6
  168. package/dist/types/decorators/parameter.d.ts.map +1 -1
  169. package/dist/types/decorators/publishSwcAppMessage.d.ts +0 -1
  170. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
  171. package/dist/types/decorators/query.d.ts +7 -7
  172. package/dist/types/decorators/query.d.ts.map +1 -1
  173. package/dist/types/decorators/requestAnimationFrame.d.ts +1 -1
  174. package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -1
  175. package/dist/types/decorators/resizeObserver.d.ts +26 -13
  176. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  177. package/dist/types/decorators/setInterval.d.ts +10 -0
  178. package/dist/types/decorators/setInterval.d.ts.map +1 -1
  179. package/dist/types/decorators/setTimeout.d.ts +10 -0
  180. package/dist/types/decorators/setTimeout.d.ts.map +1 -1
  181. package/dist/types/decorators/state.d.ts.map +1 -1
  182. package/dist/types/decorators/subscribeSwcAppMessage.d.ts +44 -0
  183. package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -0
  184. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +60 -0
  185. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +1 -0
  186. package/dist/types/decorators/swcAppRoute.d.ts +94 -0
  187. package/dist/types/decorators/swcAppRoute.d.ts.map +1 -0
  188. package/dist/types/elements/SwcApp.d.ts.map +1 -1
  189. package/dist/types/elements/SwcAppMixin.d.ts +423 -388
  190. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  191. package/dist/types/types/index.d.ts +43 -4
  192. package/dist/types/types/index.d.ts.map +1 -1
  193. package/dist/types/utils/Utils.d.ts +15 -5
  194. package/dist/types/utils/Utils.d.ts.map +1 -1
  195. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1886 -999
  196. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  197. package/package.json +8 -6
  198. package/src/SwcAppEngine.ts +1 -0
  199. package/src/decorators/addEventListener.ts +102 -96
  200. package/src/decorators/applyAttribute.ts +76 -138
  201. package/src/decorators/applyClass.ts +8 -14
  202. package/src/decorators/applyNode.ts +33 -41
  203. package/src/decorators/applyProperty.ts +51 -99
  204. package/src/decorators/applySlot.ts +3 -3
  205. package/src/decorators/applyStyle.ts +8 -14
  206. package/src/decorators/around.ts +196 -0
  207. package/src/decorators/changedAttribute.ts +39 -15
  208. package/src/decorators/elementDefine.ts +270 -219
  209. package/src/decorators/emitCustomEvent.ts +17 -13
  210. package/src/decorators/eventMedia.ts +50 -9
  211. package/src/decorators/fetch.ts +454 -0
  212. package/src/decorators/index.ts +5 -2
  213. package/src/decorators/intersectionObserver.ts +38 -24
  214. package/src/decorators/lifecycles.ts +24 -22
  215. package/src/decorators/mutationObserver.ts +71 -52
  216. package/src/decorators/parameter.ts +145 -14
  217. package/src/decorators/publishSwcAppMessage.ts +3 -4
  218. package/src/decorators/query.ts +22 -14
  219. package/src/decorators/requestAnimationFrame.ts +10 -19
  220. package/src/decorators/resizeObserver.ts +50 -29
  221. package/src/decorators/setInterval.ts +37 -26
  222. package/src/decorators/setTimeout.ts +37 -26
  223. package/src/decorators/state.ts +19 -13
  224. package/src/decorators/subscribeSwcAppMessage.ts +106 -0
  225. package/src/decorators/subscribeSwcAppRouteChange.ts +131 -0
  226. package/src/decorators/swcAppRoute.ts +231 -0
  227. package/src/elements/SwcApp.ts +40 -10
  228. package/src/elements/SwcAppMixin.ts +330 -101
  229. package/src/types/index.ts +38 -5
  230. package/src/utils/Utils.ts +50 -18
  231. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  232. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  233. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +0 -54
  234. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  235. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  236. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +0 -23
  237. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +0 -1
  238. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +0 -31
  239. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +0 -1
  240. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +0 -91
  241. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +0 -107
@@ -0,0 +1,231 @@
1
+ import { ReflectUtils } from '@dooboostore/core';
2
+ import type { RouteAction, Router, RouterMethodOptions } from '@dooboostore/core-web';
3
+ import { SwcUtils } from '../utils/Utils';
4
+ import type { HelperHostSet } from '../types';
5
+
6
+ export const SWC_APP_ROUTE_METADATA_KEY = Symbol.for('simple-web-component:swc-app-route');
7
+
8
+ export interface SwcAppRouteMetadata {
9
+ propertyKey: string | symbol;
10
+ options?: SwcAppRouteOptions;
11
+ }
12
+
13
+ /** router.go 의 이동 설정 (리턴값으로 직접 줄 때) */
14
+ export type SwcAppRouteGoConfig = { path: RouteAction; replace?: boolean; state?: RouterMethodOptions; scrollToTop?: boolean };
15
+
16
+ /**
17
+ * type 'go' 일 때 메서드 리턴값 → 이동할 곳.
18
+ * - string / RouteAction({ path, searchParams }) : router.go 로 이동
19
+ * - SwcAppRouteGoConfig({ path, replace, state, scrollToTop }) : 그대로 router.go
20
+ * - number : history 이동 (-1 = 뒤로)
21
+ * - undefined / null / false : 이동하지 않음 (조건부 이동)
22
+ */
23
+ export type SwcAppRouteGoValue = RouteAction | SwcAppRouteGoConfig | number | undefined | null | false;
24
+
25
+ /**
26
+ * 어떤 Router 메서드로 이동할지. 기본 'go'.
27
+ * - go: string / RouteAction / SwcAppRouteGoConfig / number (가드 적용)
28
+ * - push / replace: RouteAction (가드 적용)
29
+ * - pushDeleteSearchParam / replaceDeleteSearchParam / pushDeleteHashSearchParam / replaceDeleteHashSearchParam: string | string[]
30
+ * - pushAddSearchParam / replaceAddSearchParam: [[key, value], ...]
31
+ * - pushUpsertSearchParam / replaceUpsertSearchParam: { key: value | value[] }
32
+ * query 만 바꾸는 메서드는 경로가 그대로라 beforeLeave 가드 대상이 아니다.
33
+ * 어느 경우든 undefined / null / false 를 리턴하면 아무 것도 하지 않는다.
34
+ */
35
+ export type SwcAppRouteType =
36
+ | 'go' | 'push' | 'replace'
37
+ | 'pushDeleteSearchParam' | 'pushDeleteHashSearchParam' | 'pushAddSearchParam' | 'pushUpsertSearchParam'
38
+ | 'replaceDeleteSearchParam' | 'replaceDeleteHashSearchParam' | 'replaceAddSearchParam' | 'replaceUpsertSearchParam';
39
+
40
+ export interface SwcAppRouteOptions {
41
+ /** Router 메서드. 기본 'go' */
42
+ type?: SwcAppRouteType;
43
+ /** 기본 replace (type 'go' 전용. 리턴값이 SwcAppRouteGoConfig 면 그쪽이 우선) */
44
+ replace?: boolean;
45
+ /** 기본 state (go 는 SwcAppRouteGoConfig 의 state, 나머지는 두 번째 인자) */
46
+ state?: RouterMethodOptions;
47
+ /** 기본 scrollToTop (type 'go' 전용. router.go 기본값 true) */
48
+ scrollToTop?: boolean;
49
+ /** false 를 리턴하면 이동하지 않는다. target = 이동을 하는 Router, value = valueKey 로 꺼낸 리턴값 */
50
+ filter?: (target: Router, value: any, meta: { currentThis: any; helper: HelperHostSet }) => boolean;
51
+ /**
52
+ * Custom key to extract value from return object.
53
+ * If not provided, uses SWC_APP_ROUTE_METADATA_KEY by default.
54
+ * Useful when this decorator is stacked with others on the same method.
55
+ *
56
+ * Example:
57
+ * @swcAppRoute({ valueKey: 'go' })
58
+ * @publishSwcAppMessage('saved', { valueKey: 'saved' })
59
+ * save() {
60
+ * return { go: '/done', saved: { id: 1 } };
61
+ * }
62
+ */
63
+ valueKey?: symbol | string;
64
+ }
65
+
66
+ const isGoConfig = (v: any): v is SwcAppRouteGoConfig =>
67
+ !!v && typeof v === 'object' && 'path' in v && ('replace' in v || 'state' in v || 'scrollToTop' in v || typeof v.path === 'object');
68
+
69
+ function createSwcAppRoute(options?: SwcAppRouteOptions): MethodDecorator {
70
+ return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
71
+ const constructor = target.constructor;
72
+ let list = ReflectUtils.getOwnMetadata(SWC_APP_ROUTE_METADATA_KEY, constructor) as SwcAppRouteMetadata[];
73
+ if (!list) {
74
+ list = [];
75
+ ReflectUtils.defineMetadata(SWC_APP_ROUTE_METADATA_KEY, list, constructor);
76
+ }
77
+ list.push({ propertyKey, options });
78
+
79
+ if (!descriptor) {
80
+ return descriptor;
81
+ }
82
+
83
+ // 메서드 래핑 - 원본 메서드의 반환값으로 이동 (DI 로 router 를 받을 필요 없음: 요소가 속한 SwcApp 의 router 사용)
84
+ const originalMethod = descriptor.value;
85
+ descriptor.value = function (...args: any[]) {
86
+ const result = originalMethod.apply(this, args);
87
+
88
+ /**
89
+ * Extract value for this decorator from method return value
90
+ *
91
+ * If return value is an object with this decorator's key,
92
+ * use that value. Otherwise use the entire return value.
93
+ *
94
+ * Uses valueKey from options if provided, otherwise uses SWC_APP_ROUTE_METADATA_KEY.
95
+ */
96
+ const extractValue = (v: any) => {
97
+ const keyToUse = options?.valueKey ?? SWC_APP_ROUTE_METADATA_KEY;
98
+ if (v && typeof v === 'object' && keyToUse in v) {
99
+ return v[keyToUse];
100
+ }
101
+ return v;
102
+ };
103
+
104
+ const route = (value: any) => {
105
+ if (value === undefined || value === null || value === false) return;
106
+ const router = SwcUtils.getAppHost(this as HTMLElement)?.router;
107
+ if (!router) {
108
+ console.warn('swcAppRoute: no SwcApp router found for', this);
109
+ return;
110
+ }
111
+ if (options?.filter) {
112
+ const helper = SwcUtils.getHelperAndHostSet(this as HTMLElement);
113
+ if (!options.filter(router, value, { currentThis: this, helper })) return;
114
+ }
115
+ const type = options?.type ?? 'go';
116
+ if (type === 'go') {
117
+ if (typeof value === 'number') return router.go(value);
118
+ const defaults = { replace: options?.replace, state: options?.state, scrollToTop: options?.scrollToTop };
119
+ return router.go(isGoConfig(value) ? { ...defaults, ...value } : { ...defaults, path: value as RouteAction });
120
+ }
121
+ const state = options?.state;
122
+ // push/replace 는 경로가 바뀌므로 go 와 같이 beforeLeave 가드를 거친다 (가드 없으면 동기)
123
+ if ((type === 'push' || type === 'replace') && router.hasLeaveGuards) {
124
+ return router.canLeave(router.getRouteData({ pathOrUrl: router.toUrl(value) }), router.value).then(ok => {
125
+ if (!ok) return;
126
+ if (type === 'push') router.push(value as RouteAction, state);
127
+ else router.replace(value as RouteAction, state);
128
+ });
129
+ }
130
+ switch (type) {
131
+ case 'push':
132
+ return router.push(value as RouteAction, state);
133
+ case 'replace':
134
+ return router.replace(value as RouteAction, state);
135
+ case 'pushDeleteSearchParam':
136
+ return router.pushDeleteSearchParam(value as string | string[], state);
137
+ case 'pushDeleteHashSearchParam':
138
+ return router.pushDeleteHashSearchParam(value as string | string[], state);
139
+ case 'pushAddSearchParam':
140
+ return router.pushAddSearchParam(value as [[string, string]], state);
141
+ case 'pushUpsertSearchParam':
142
+ return router.pushUpsertSearchParam(value as Record<string, string | string[]>, state);
143
+ case 'replaceDeleteSearchParam':
144
+ return router.replaceDeleteSearchParam(value as string | string[], state);
145
+ case 'replaceDeleteHashSearchParam':
146
+ return router.replaceDeleteHashSearchParam(value as string | string[], state);
147
+ case 'replaceAddSearchParam':
148
+ return router.replaceAddSearchParam(value as [[string, string]], state);
149
+ case 'replaceUpsertSearchParam':
150
+ return router.replaceUpsertSearchParam(value as Record<string, string | string[]>, state);
151
+ }
152
+ };
153
+
154
+ // Promise 체크
155
+ if (result instanceof Promise) {
156
+ result
157
+ .then(data => route(extractValue(data)))
158
+ .catch(err => {
159
+ console.warn('swcAppRoute async error:', err);
160
+ });
161
+ } else {
162
+ route(extractValue(result));
163
+ }
164
+
165
+ return result;
166
+ };
167
+
168
+ return descriptor;
169
+ };
170
+ }
171
+
172
+ // 오버로드 시그니처 - 직접 사용 (괄호 없음)
173
+ export function swcAppRoute(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
174
+ // 오버로드 시그니처 - 함수 호출 (괄호 있음)
175
+ export function swcAppRoute(options: SwcAppRouteOptions): MethodDecorator;
176
+
177
+ export function swcAppRoute(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
178
+ // 직접 데코레이터로 사용된 경우 (괄호 없음): @swcAppRoute
179
+ if (targetOrOptions && typeof targetOrOptions === 'object' && propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol') && descriptor) {
180
+ return createSwcAppRoute()(targetOrOptions, propertyKey, descriptor);
181
+ }
182
+ // 함수로 호출된 경우 (인자 있음): @swcAppRoute({...})
183
+ return createSwcAppRoute(targetOrOptions as SwcAppRouteOptions | undefined);
184
+ }
185
+
186
+ // --- Aliases ---
187
+
188
+ /** type 을 고정한 별칭. @swcAppRoutePush / @swcAppRoutePush({ state }) 둘 다. replace/scrollToTop 은 go 전용 */
189
+ type SwcAppRouteTypedOptions<T extends SwcAppRouteType> = T extends 'go'
190
+ ? Omit<SwcAppRouteOptions, 'type'>
191
+ : Omit<SwcAppRouteOptions, 'type' | 'replace' | 'scrollToTop'>;
192
+ type SwcAppRouteTypedDecorator<T extends SwcAppRouteType> = {
193
+ (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
194
+ (options: SwcAppRouteTypedOptions<T>): MethodDecorator; // 빈 괄호 금지 — 인자가 없으면 bare
195
+ };
196
+ const typedRoute = <T extends SwcAppRouteType>(type: T): SwcAppRouteTypedDecorator<T> =>
197
+ ((targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any => {
198
+ if (targetOrOptions && typeof targetOrOptions === 'object' && propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol') && descriptor) {
199
+ return createSwcAppRoute({ type })(targetOrOptions, propertyKey, descriptor);
200
+ }
201
+ return createSwcAppRoute({ ...(targetOrOptions ?? {}), type });
202
+ }) as SwcAppRouteTypedDecorator<T>;
203
+
204
+ /** 리턴: string / RouteAction / SwcAppRouteGoConfig / number → router.go */
205
+ export const swcAppRouteGo = typedRoute('go');
206
+ /** 리턴: RouteAction → router.push */
207
+ export const swcAppRoutePush = typedRoute('push');
208
+ /** 리턴: RouteAction → router.replace */
209
+ export const swcAppRouteReplace = typedRoute('replace');
210
+ /** 리턴: string | string[] → router.pushDeleteSearchParam */
211
+ export const swcAppRoutePushDeleteSearchParam = typedRoute('pushDeleteSearchParam');
212
+ /** 리턴: string | string[] → router.pushDeleteHashSearchParam */
213
+ export const swcAppRoutePushDeleteHashSearchParam = typedRoute('pushDeleteHashSearchParam');
214
+ /** 리턴: [[key, value], ...] → router.pushAddSearchParam */
215
+ export const swcAppRoutePushAddSearchParam = typedRoute('pushAddSearchParam');
216
+ /** 리턴: { key: value | value[] } → router.pushUpsertSearchParam */
217
+ export const swcAppRoutePushUpsertSearchParam = typedRoute('pushUpsertSearchParam');
218
+ /** 리턴: string | string[] → router.replaceDeleteSearchParam */
219
+ export const swcAppRouteReplaceDeleteSearchParam = typedRoute('replaceDeleteSearchParam');
220
+ /** 리턴: string | string[] → router.replaceDeleteHashSearchParam */
221
+ export const swcAppRouteReplaceDeleteHashSearchParam = typedRoute('replaceDeleteHashSearchParam');
222
+ /** 리턴: [[key, value], ...] → router.replaceAddSearchParam */
223
+ export const swcAppRouteReplaceAddSearchParam = typedRoute('replaceAddSearchParam');
224
+ /** 리턴: { key: value | value[] } → router.replaceUpsertSearchParam */
225
+ export const swcAppRouteReplaceUpsertSearchParam = typedRoute('replaceUpsertSearchParam');
226
+
227
+ // Helper function to retrieve route metadata
228
+ export const getSwcAppRouteMetadata = (target: any): SwcAppRouteMetadata[] | undefined => {
229
+ const constructor = typeof target === 'function' ? target : target.constructor;
230
+ return ReflectUtils.findAllMetadata<any[]>(SWC_APP_ROUTE_METADATA_KEY, constructor).flat();
231
+ };
@@ -18,7 +18,10 @@ export const defineSwcApp = async (w: Window) => {
18
18
 
19
19
  @elementDefine(swcAppTagName, {window: w})
20
20
  class SwcAppImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
21
- // SwcAppMixin에서 모든 기능을 상속받음
21
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
22
+ onConnected(): void {}
23
+ onDisconnected(): void {}
24
+ onSwcAppConnected(): void {}
22
25
  }
23
26
 
24
27
  return w.customElements.whenDefined(swcAppTagName);
@@ -39,7 +42,10 @@ export const defineSwcAppBody = async (w: Window) => {
39
42
 
40
43
  @elementDefine(swcAppBodyTagName, {window: w, extends: 'body'})
41
44
  class SwcAppBodyImpl extends SwcAppMixin(w.HTMLBodyElement) implements SwcAppInterface {
42
- // SwcAppMixin에서 모든 기능을 상속받음
45
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
46
+ onConnected(): void {}
47
+ onDisconnected(): void {}
48
+ onSwcAppConnected(): void {}
43
49
  }
44
50
  return w.customElements.whenDefined(swcAppBodyTagName);
45
51
  };
@@ -59,7 +65,10 @@ export const defineSwcAppDiv = async (w: Window) => {
59
65
 
60
66
  @elementDefine(swcAppDivTagName, {window: w, extends: 'div'})
61
67
  class SwcAppDivImpl extends SwcAppMixin(w.HTMLDivElement) implements SwcAppInterface {
62
- // SwcAppMixin에서 모든 기능을 상속받음
68
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
69
+ onConnected(): void {}
70
+ onDisconnected(): void {}
71
+ onSwcAppConnected(): void {}
63
72
  }
64
73
 
65
74
  return w.customElements.whenDefined(swcAppDivTagName);
@@ -80,7 +89,10 @@ export const defineSwcAppSection = async (w: Window) => {
80
89
 
81
90
  @elementDefine(swcAppSectionTagName, {window: w, extends: 'section'})
82
91
  class SwcAppSectionImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
83
- // SwcAppMixin에서 모든 기능을 상속받음
92
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
93
+ onConnected(): void {}
94
+ onDisconnected(): void {}
95
+ onSwcAppConnected(): void {}
84
96
  }
85
97
 
86
98
  return w.customElements.whenDefined(swcAppSectionTagName);
@@ -101,7 +113,10 @@ export const defineSwcAppMain = async (w: Window) => {
101
113
 
102
114
  @elementDefine(swcAppMainTagName, {window: w, extends: 'main'})
103
115
  class SwcAppMainImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
104
- // SwcAppMixin에서 모든 기능을 상속받음
116
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
117
+ onConnected(): void {}
118
+ onDisconnected(): void {}
119
+ onSwcAppConnected(): void {}
105
120
  }
106
121
 
107
122
  return w.customElements.whenDefined(swcAppMainTagName);
@@ -122,7 +137,10 @@ export const defineSwcAppArticle = async (w: Window) => {
122
137
 
123
138
  @elementDefine(swcAppArticleTagName, {window: w, extends: 'article'})
124
139
  class SwcAppArticleImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
125
- // SwcAppMixin에서 모든 기능을 상속받음
140
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
141
+ onConnected(): void {}
142
+ onDisconnected(): void {}
143
+ onSwcAppConnected(): void {}
126
144
  }
127
145
 
128
146
  return w.customElements.whenDefined(swcAppArticleTagName);
@@ -143,7 +161,10 @@ export const defineSwcAppHeader = async (w: Window) => {
143
161
 
144
162
  @elementDefine(swcAppHeaderTagName, {window: w, extends: 'header'})
145
163
  class SwcAppHeaderImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
146
- // SwcAppMixin에서 모든 기능을 상속받음
164
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
165
+ onConnected(): void {}
166
+ onDisconnected(): void {}
167
+ onSwcAppConnected(): void {}
147
168
  }
148
169
 
149
170
  return w.customElements.whenDefined(swcAppHeaderTagName);
@@ -164,7 +185,10 @@ export const defineSwcAppFooter = async (w: Window) => {
164
185
 
165
186
  @elementDefine(swcAppFooterTagName, {window: w, extends: 'footer'})
166
187
  class SwcAppFooterImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
167
- // SwcAppMixin에서 모든 기능을 상속받음
188
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
189
+ onConnected(): void {}
190
+ onDisconnected(): void {}
191
+ onSwcAppConnected(): void {}
168
192
  }
169
193
 
170
194
  return w.customElements.whenDefined(swcAppFooterTagName);
@@ -185,7 +209,10 @@ export const defineSwcAppNav = async (w: Window) => {
185
209
 
186
210
  @elementDefine(swcAppNavTagName, {window: w, extends: 'nav'})
187
211
  class SwcAppNavImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
188
- // SwcAppMixin에서 모든 기능을 상속받음
212
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
213
+ onConnected(): void {}
214
+ onDisconnected(): void {}
215
+ onSwcAppConnected(): void {}
189
216
  }
190
217
 
191
218
  return w.customElements.whenDefined(swcAppNavTagName);
@@ -206,7 +233,10 @@ export const defineSwcAppAside = async (w: Window) => {
206
233
 
207
234
  @elementDefine(swcAppAsideTagName, {window: w, extends: 'aside'})
208
235
  class SwcAppAsideImpl extends SwcAppMixin(w.HTMLElement) implements SwcAppInterface {
209
- // SwcAppMixin에서 모든 기능을 상속받음
236
+ // SwcAppMixin에서 모든 기능을 상속받음. 기본 요소라 훅에서 할 일은 없음.
237
+ onConnected(): void {}
238
+ onDisconnected(): void {}
239
+ onSwcAppConnected(): void {}
210
240
  }
211
241
 
212
242
  return w.customElements.whenDefined(swcAppAsideTagName);