@dooboostore/simple-web-component 1.0.50 → 1.0.52
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.
- package/README.md +735 -354
- package/dist/cjs/SwcAppEngine.js.map +2 -2
- package/dist/cjs/decorators/addEventListener.js +64 -146
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +36 -48
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +9 -12
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +14 -22
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyProperty.js +12 -42
- package/dist/cjs/decorators/applyProperty.js.map +2 -2
- package/dist/cjs/decorators/applySlot.js +3 -3
- package/dist/cjs/decorators/applySlot.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +9 -12
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/around.js +124 -0
- package/dist/cjs/decorators/around.js.map +7 -0
- package/dist/cjs/decorators/changedAttribute.js +40 -12
- package/dist/cjs/decorators/changedAttribute.js.map +2 -2
- package/dist/cjs/decorators/elementDefine.js +224 -195
- package/dist/cjs/decorators/elementDefine.js.map +3 -3
- package/dist/cjs/decorators/emitCustomEvent.js +14 -12
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/eventMedia.js +36 -8
- package/dist/cjs/decorators/eventMedia.js.map +2 -2
- package/dist/cjs/decorators/fetch.js +278 -0
- package/dist/cjs/decorators/fetch.js.map +7 -0
- package/dist/cjs/decorators/index.js +5 -2
- package/dist/cjs/decorators/index.js.map +2 -2
- package/dist/cjs/decorators/intersectionObserver.js +33 -13
- package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
- package/dist/cjs/decorators/lifecycles.js +11 -11
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/mutationObserver.js +55 -39
- package/dist/cjs/decorators/mutationObserver.js.map +3 -3
- package/dist/cjs/decorators/parameter.js +92 -9
- package/dist/cjs/decorators/parameter.js.map +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js +2 -2
- package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/cjs/decorators/query.js +11 -5
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/requestAnimationFrame.js +7 -16
- package/dist/cjs/decorators/requestAnimationFrame.js.map +2 -2
- package/dist/cjs/decorators/resizeObserver.js +41 -17
- package/dist/cjs/decorators/resizeObserver.js.map +3 -3
- package/dist/cjs/decorators/setInterval.js +36 -25
- package/dist/cjs/decorators/setInterval.js.map +2 -2
- package/dist/cjs/decorators/setTimeout.js +36 -25
- package/dist/cjs/decorators/setTimeout.js.map +2 -2
- package/dist/cjs/decorators/state.js +13 -10
- package/dist/cjs/decorators/state.js.map +2 -2
- package/dist/cjs/decorators/{subscribeSwcAppMessageWhileConnected.js → subscribeSwcAppMessage.js} +20 -21
- package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +7 -0
- package/dist/cjs/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +23 -19
- package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +7 -0
- package/dist/cjs/decorators/swcAppRoute.js +149 -0
- package/dist/cjs/decorators/swcAppRoute.js.map +7 -0
- package/dist/cjs/elements/SwcApp.js +70 -0
- package/dist/cjs/elements/SwcApp.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js +262 -83
- package/dist/cjs/elements/SwcAppMixin.js.map +3 -3
- package/dist/cjs/types/index.js +5 -1
- package/dist/cjs/types/index.js.map +2 -2
- package/dist/cjs/utils/Utils.js +36 -15
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/SwcAppEngine.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +64 -146
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +36 -48
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +9 -12
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +15 -23
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyProperty.js +12 -42
- package/dist/esm/decorators/applyProperty.js.map +2 -2
- package/dist/esm/decorators/applySlot.js +3 -3
- package/dist/esm/decorators/applySlot.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +9 -12
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/around.js +105 -0
- package/dist/esm/decorators/around.js.map +7 -0
- package/dist/esm/decorators/changedAttribute.js +40 -12
- package/dist/esm/decorators/changedAttribute.js.map +2 -2
- package/dist/esm/decorators/elementDefine.js +222 -193
- package/dist/esm/decorators/elementDefine.js.map +3 -3
- package/dist/esm/decorators/emitCustomEvent.js +15 -13
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/eventMedia.js +36 -8
- package/dist/esm/decorators/eventMedia.js.map +2 -2
- package/dist/esm/decorators/fetch.js +259 -0
- package/dist/esm/decorators/fetch.js.map +7 -0
- package/dist/esm/decorators/index.js +5 -2
- package/dist/esm/decorators/index.js.map +2 -2
- package/dist/esm/decorators/intersectionObserver.js +33 -13
- package/dist/esm/decorators/intersectionObserver.js.map +2 -2
- package/dist/esm/decorators/lifecycles.js +11 -11
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/mutationObserver.js +55 -39
- package/dist/esm/decorators/mutationObserver.js.map +3 -3
- package/dist/esm/decorators/parameter.js +92 -9
- package/dist/esm/decorators/parameter.js.map +2 -2
- package/dist/esm/decorators/publishSwcAppMessage.js +2 -2
- package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
- package/dist/esm/decorators/query.js +11 -5
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/requestAnimationFrame.js +8 -17
- package/dist/esm/decorators/requestAnimationFrame.js.map +2 -2
- package/dist/esm/decorators/resizeObserver.js +41 -17
- package/dist/esm/decorators/resizeObserver.js.map +2 -2
- package/dist/esm/decorators/setInterval.js +37 -26
- package/dist/esm/decorators/setInterval.js.map +2 -2
- package/dist/esm/decorators/setTimeout.js +37 -26
- package/dist/esm/decorators/setTimeout.js.map +2 -2
- package/dist/esm/decorators/state.js +13 -10
- package/dist/esm/decorators/state.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppMessage.js +53 -0
- package/dist/esm/decorators/subscribeSwcAppMessage.js.map +7 -0
- package/dist/esm/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +20 -16
- package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +7 -0
- package/dist/esm/decorators/swcAppRoute.js +130 -0
- package/dist/esm/decorators/swcAppRoute.js.map +7 -0
- package/dist/esm/elements/SwcApp.js +70 -0
- package/dist/esm/elements/SwcApp.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +264 -85
- package/dist/esm/elements/SwcAppMixin.js.map +3 -3
- package/dist/esm/types/index.js +5 -1
- package/dist/esm/types/index.js.map +2 -2
- package/dist/esm/utils/Utils.js +36 -15
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1893 -1000
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/SwcAppEngine.d.ts +1 -0
- package/dist/types/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/decorators/addEventListener.d.ts +923 -960
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +26 -38
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +1 -3
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +15 -17
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyProperty.d.ts +25 -45
- package/dist/types/decorators/applyProperty.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +1 -3
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/around.d.ts +87 -0
- package/dist/types/decorators/around.d.ts.map +1 -0
- package/dist/types/decorators/changedAttribute.d.ts +21 -1
- package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +0 -1
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/eventMedia.d.ts +24 -1
- package/dist/types/decorators/eventMedia.d.ts.map +1 -1
- package/dist/types/decorators/fetch.d.ts +139 -0
- package/dist/types/decorators/fetch.d.ts.map +1 -0
- package/dist/types/decorators/index.d.ts +5 -2
- package/dist/types/decorators/index.d.ts.map +1 -1
- package/dist/types/decorators/intersectionObserver.d.ts +24 -11
- package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
- package/dist/types/decorators/lifecycles.d.ts +8 -7
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/mutationObserver.d.ts +26 -13
- package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
- package/dist/types/decorators/parameter.d.ts +84 -6
- package/dist/types/decorators/parameter.d.ts.map +1 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts +0 -1
- package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +7 -7
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/requestAnimationFrame.d.ts +1 -1
- package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -1
- package/dist/types/decorators/resizeObserver.d.ts +26 -13
- package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
- package/dist/types/decorators/setInterval.d.ts +10 -0
- package/dist/types/decorators/setInterval.d.ts.map +1 -1
- package/dist/types/decorators/setTimeout.d.ts +10 -0
- package/dist/types/decorators/setTimeout.d.ts.map +1 -1
- package/dist/types/decorators/state.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts +44 -0
- package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -0
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +60 -0
- package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +1 -0
- package/dist/types/decorators/swcAppRoute.d.ts +94 -0
- package/dist/types/decorators/swcAppRoute.d.ts.map +1 -0
- package/dist/types/elements/SwcApp.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +423 -388
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/types/index.d.ts +43 -4
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts +15 -5
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1893 -1000
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +8 -6
- package/src/SwcAppEngine.ts +1 -0
- package/src/decorators/addEventListener.ts +102 -96
- package/src/decorators/applyAttribute.ts +76 -138
- package/src/decorators/applyClass.ts +8 -14
- package/src/decorators/applyNode.ts +33 -41
- package/src/decorators/applyProperty.ts +51 -99
- package/src/decorators/applySlot.ts +3 -3
- package/src/decorators/applyStyle.ts +8 -14
- package/src/decorators/around.ts +196 -0
- package/src/decorators/changedAttribute.ts +39 -15
- package/src/decorators/elementDefine.ts +270 -219
- package/src/decorators/emitCustomEvent.ts +17 -13
- package/src/decorators/eventMedia.ts +50 -9
- package/src/decorators/fetch.ts +454 -0
- package/src/decorators/index.ts +5 -2
- package/src/decorators/intersectionObserver.ts +38 -24
- package/src/decorators/lifecycles.ts +24 -22
- package/src/decorators/mutationObserver.ts +71 -52
- package/src/decorators/parameter.ts +145 -14
- package/src/decorators/publishSwcAppMessage.ts +3 -4
- package/src/decorators/query.ts +22 -14
- package/src/decorators/requestAnimationFrame.ts +10 -19
- package/src/decorators/resizeObserver.ts +50 -29
- package/src/decorators/setInterval.ts +37 -26
- package/src/decorators/setTimeout.ts +37 -26
- package/src/decorators/state.ts +19 -13
- package/src/decorators/subscribeSwcAppMessage.ts +106 -0
- package/src/decorators/subscribeSwcAppRouteChange.ts +131 -0
- package/src/decorators/swcAppRoute.ts +231 -0
- package/src/elements/SwcApp.ts +40 -10
- package/src/elements/SwcAppMixin.ts +340 -101
- package/src/types/index.ts +38 -5
- package/src/utils/Utils.ts +50 -18
- package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +0 -54
- package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +0 -23
- package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +0 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +0 -31
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +0 -1
- package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +0 -91
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +0 -107
|
@@ -1,35 +1,45 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @eventObject/@matchedElement/@hostSet/@helperHostSet/@helperSet/@
|
|
5
|
-
* @
|
|
4
|
+
* @eventObject/@matchedElement/@hostSet/@helperHostSet/@helperSet/@swcAppRouterEvent/@appMessage/@eventBeforeReturn —
|
|
5
|
+
* @event/lifecycle/subscribeSwcAppRouteChange/subscribeSwcAppMessage
|
|
6
6
|
* 계열 핸들러의 파라미터를 순서 무관하게 선언할 수 있게 해주는 파라미터 데코레이터.
|
|
7
7
|
* @dooboostore/simple-boot의 @Inject와 동일한 인덱스 기반 메타데이터 패턴을 따른다:
|
|
8
8
|
* 데코레이터가 실행되는 순서가 아니라 실제 parameterIndex로 슬롯을 매칭하므로,
|
|
9
9
|
* 사용자가 파라미터 선언 순서를 자유롭게 바꿔도 된다.
|
|
10
10
|
*/
|
|
11
|
-
export type SwcParamKind = '
|
|
11
|
+
export type SwcParamKind = 'eventObject' | 'matchedElement' | 'hostSet' | 'helperHostSet' | 'helperSet' | 'swcAppRouterEvent' | 'appMessage' | 'eventBeforeReturn' | 'appMessageBeforeReturn' | 'routeChangeBeforeReturn' | 'eventMediaBeforeReturn' | 'mutationObserverBeforeReturn' | 'intersectionObserverBeforeReturn' | 'resizeObserverBeforeReturn' | 'changedAttributeBeforeReturn' | 'setTimeoutBeforeReturn' | 'setIntervalBeforeReturn' | 'fetchSettled'
|
|
12
|
+
| SwcRouteParamKind;
|
|
13
|
+
|
|
14
|
+
/** 라우트 핸들러 전용 (subscribeSwcAppRouteChange 가 채움). kind 이름 = 데코레이터 이름 */
|
|
15
|
+
export type SwcRouteParamKind =
|
|
16
|
+
| 'swcAppRouteQueryParam' | 'swcAppRouteFirstQueryParam' | 'swcAppRouteLastQueryParam' | 'swcAppRouteQueryParams'
|
|
17
|
+
| 'swcAppRouteQueryParamObject' | 'swcAppRouteFirstQueryParamObject' | 'swcAppRouteLastQueryParamObject' | 'swcAppRouteQueryParamsObject'
|
|
18
|
+
| 'swcAppRouteURLSearchParams'
|
|
19
|
+
| 'swcAppRoutePathVariable' | 'swcAppRouteFirstPathVariable' | 'swcAppRouteLastPathVariable' | 'swcAppRoutePathVariables'
|
|
20
|
+
| 'swcAppRoutePathVariableObject' | 'swcAppRouteFirstPathVariableObject' | 'swcAppRouteLastPathVariableObject' | 'swcAppRoutePathVariablesObject';
|
|
12
21
|
|
|
13
22
|
const SWC_PARAMETER_METADATA_KEY = Symbol.for('simple-web-component:parameter');
|
|
14
23
|
|
|
15
|
-
|
|
24
|
+
/** key: @swcAppRouteQueryParam('q') 처럼 키를 받는 파라미터 데코레이터의 키 */
|
|
25
|
+
type SaveParamConfig = { index: number; kind: SwcParamKind; key?: string };
|
|
16
26
|
|
|
17
|
-
const registerParam = (kind: SwcParamKind, target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => {
|
|
27
|
+
const registerParam = (kind: SwcParamKind, target: Object, propertyKey: string | symbol | undefined, parameterIndex: number, key?: string) => {
|
|
18
28
|
if (!propertyKey) return;
|
|
19
29
|
const constructor = target.constructor;
|
|
20
30
|
const saves = (ReflectUtils.getOwnMetadata(SWC_PARAMETER_METADATA_KEY, constructor, propertyKey) ?? []) as SaveParamConfig[];
|
|
21
|
-
saves.push({ index: parameterIndex, kind });
|
|
31
|
+
saves.push(key === undefined ? { index: parameterIndex, kind } : { index: parameterIndex, kind, key });
|
|
22
32
|
ReflectUtils.defineMetadata(SWC_PARAMETER_METADATA_KEY, saves, constructor, propertyKey);
|
|
23
33
|
};
|
|
24
34
|
|
|
25
35
|
/** 이벤트 핸들러의 원본 Event 객체를 주입한다. */
|
|
26
36
|
export function eventObject(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
27
|
-
registerParam('
|
|
37
|
+
registerParam('eventObject', target, propertyKey, parameterIndex);
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
/** delegate로 매칭된 실제 엘리먼트($matchedElement)를 주입한다. */
|
|
31
41
|
export function matchedElement(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
32
|
-
registerParam('
|
|
42
|
+
registerParam('matchedElement', target, propertyKey, parameterIndex);
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
/** HostSet(호스트 트리 정보 — $host/$hosts/$firstHost/$appHost 등)을 주입한다. */
|
|
@@ -47,18 +57,91 @@ export function helperSet(target: Object, propertyKey: string | symbol, paramete
|
|
|
47
57
|
registerParam('helperSet', target, propertyKey, parameterIndex);
|
|
48
58
|
}
|
|
49
59
|
|
|
50
|
-
/** @
|
|
51
|
-
export function
|
|
52
|
-
registerParam('
|
|
60
|
+
/** @subscribeSwcAppRouteChange 핸들러의 라우트 변경 이벤트({...RouterEventType, pathData})를 주입한다. */
|
|
61
|
+
export function swcAppRouterEvent(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
62
|
+
registerParam('swcAppRouterEvent', target, propertyKey, parameterIndex);
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
/** @
|
|
65
|
+
/** @subscribeSwcAppMessage 핸들러의 SwcAppMessage 페이로드를 주입한다. */
|
|
56
66
|
export function appMessage(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
57
67
|
registerParam('appMessage', target, propertyKey, parameterIndex);
|
|
58
68
|
}
|
|
59
69
|
|
|
70
|
+
/**
|
|
71
|
+
* @event 계열의 before 훅이 이번 호출에 리턴한 값을 주입한다.
|
|
72
|
+
* (before에서 async로 준비한 데이터를 핸들러가 받는 용도. before 없으면 undefined)
|
|
73
|
+
* 예: @eventClick({ before: () => loadUser() }) onClick(@eventBeforeReturn user) { ... }
|
|
74
|
+
*/
|
|
75
|
+
export function eventBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
76
|
+
registerParam('eventBeforeReturn', target, propertyKey, parameterIndex);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @subscribeSwcAppMessage 의 before 훅이 이번 호출에 리턴한 값을 주입한다.
|
|
81
|
+
* (before에서 async로 준비한 데이터를 핸들러가 받는 용도. 없으면 undefined)
|
|
82
|
+
* 예: onMsg(@appMessage m, @appMessageBeforeReturn prepared) { ... }
|
|
83
|
+
*/
|
|
84
|
+
export function appMessageBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
85
|
+
registerParam('appMessageBeforeReturn', target, propertyKey, parameterIndex);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @subscribeSwcAppRouteChange 의 before 훅이 이번 호출에 리턴한 값을 주입한다.
|
|
90
|
+
* (before에서 async 가드/준비한 데이터를 핸들러가 받는 용도. 없으면 undefined)
|
|
91
|
+
* 예: routeChanged(@swcAppRouterEvent e, @routeChangeBeforeReturn guard) { ... }
|
|
92
|
+
*/
|
|
93
|
+
export function routeChangeBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
94
|
+
registerParam('routeChangeBeforeReturn', target, propertyKey, parameterIndex);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @eventMedia 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined)
|
|
99
|
+
* 예: @eventMediaChange('(max-width:600px)', { before: () => ... }) onMobile(@eventMediaBeforeReturn v) { ... }
|
|
100
|
+
*/
|
|
101
|
+
export function eventMediaBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
102
|
+
registerParam('eventMediaBeforeReturn', target, propertyKey, parameterIndex);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @mutationObserver 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
106
|
+
export function mutationObserverBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
107
|
+
registerParam('mutationObserverBeforeReturn', target, propertyKey, parameterIndex);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** @intersectionObserver 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
111
|
+
export function intersectionObserverBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
112
|
+
registerParam('intersectionObserverBeforeReturn', target, propertyKey, parameterIndex);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** @resizeObserver 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
116
|
+
export function resizeObserverBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
117
|
+
registerParam('resizeObserverBeforeReturn', target, propertyKey, parameterIndex);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** @changedAttribute 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
121
|
+
export function changedAttributeBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
122
|
+
registerParam('changedAttributeBeforeReturn', target, propertyKey, parameterIndex);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** @setTimeout(type:'onConnected') 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
126
|
+
export function setTimeoutBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
127
|
+
registerParam('setTimeoutBeforeReturn', target, propertyKey, parameterIndex);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** @setInterval(type:'onConnected') 의 before 훅이 이번 호출에 리턴한 값을 주입한다. (before 없으면 undefined) */
|
|
131
|
+
export function setIntervalBeforeReturn(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
132
|
+
registerParam('setIntervalBeforeReturn', target, propertyKey, parameterIndex);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @fetch(trigger:'before') 의 fetch settled 결과(PromiseSettledResult)를 주입한다.
|
|
137
|
+
* 예: save(@fetchSettled settled) { ... }
|
|
138
|
+
*/
|
|
139
|
+
export function fetchSettled(target: Object, propertyKey: string | symbol, parameterIndex: number): void {
|
|
140
|
+
registerParam('fetchSettled', target, propertyKey, parameterIndex);
|
|
141
|
+
}
|
|
142
|
+
|
|
60
143
|
export const getParameterMetadata = (target: any, propertyKey: string | symbol): SaveParamConfig[] => {
|
|
61
|
-
const constructor = target
|
|
144
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
62
145
|
return ReflectUtils.getMetadata(SWC_PARAMETER_METADATA_KEY, constructor, propertyKey) ?? [];
|
|
63
146
|
};
|
|
64
147
|
|
|
@@ -76,6 +159,54 @@ export const buildSwcParameterArgs = (
|
|
|
76
159
|
if (saves.length === 0) return legacyArgs;
|
|
77
160
|
const maxIndex = Math.max(...saves.map(s => s.index));
|
|
78
161
|
const args: any[] = new Array(maxIndex + 1);
|
|
79
|
-
for (const s of saves)
|
|
162
|
+
for (const s of saves) {
|
|
163
|
+
const value = kindValues[s.kind];
|
|
164
|
+
// 키를 받는 kind 는 kindValues 에 (key) => 값 resolver 가 들어 있다
|
|
165
|
+
args[s.index] = s.key !== undefined && typeof value === 'function' ? value(s.key) : value;
|
|
166
|
+
}
|
|
80
167
|
return args;
|
|
81
168
|
};
|
|
169
|
+
|
|
170
|
+
// ─── 라우트 파라미터 (@subscribeSwcAppRouteChange 핸들러) ───
|
|
171
|
+
// 규칙: 접두어 없음 = First, First/Last = 같은 키가 여러 번일 때 첫/마지막 값, 복수형 = 모든 값 배열.
|
|
172
|
+
|
|
173
|
+
const keyedRouteParam = (kind: SwcRouteParamKind) => (key: string): ParameterDecorator =>
|
|
174
|
+
(target, propertyKey, parameterIndex) => registerParam(kind, target, propertyKey, parameterIndex, key);
|
|
175
|
+
const routeParam = (kind: SwcRouteParamKind): ParameterDecorator =>
|
|
176
|
+
(target, propertyKey, parameterIndex) => registerParam(kind, target, propertyKey, parameterIndex);
|
|
177
|
+
|
|
178
|
+
/** ?tag=a&tag=b → @swcAppRouteQueryParam('tag') = 'a' (없으면 null) */
|
|
179
|
+
export const swcAppRouteQueryParam = keyedRouteParam('swcAppRouteQueryParam');
|
|
180
|
+
/** = swcAppRouteQueryParam */
|
|
181
|
+
export const swcAppRouteFirstQueryParam = keyedRouteParam('swcAppRouteFirstQueryParam');
|
|
182
|
+
/** ?tag=a&tag=b → 'b' */
|
|
183
|
+
export const swcAppRouteLastQueryParam = keyedRouteParam('swcAppRouteLastQueryParam');
|
|
184
|
+
/** ?tag=a&tag=b → ['a', 'b'] */
|
|
185
|
+
export const swcAppRouteQueryParams = keyedRouteParam('swcAppRouteQueryParams');
|
|
186
|
+
/** ?tag=a&tag=b → { tag: 'a' } */
|
|
187
|
+
export const swcAppRouteQueryParamObject = routeParam('swcAppRouteQueryParamObject');
|
|
188
|
+
/** = swcAppRouteQueryParamObject */
|
|
189
|
+
export const swcAppRouteFirstQueryParamObject = routeParam('swcAppRouteFirstQueryParamObject');
|
|
190
|
+
/** ?tag=a&tag=b → { tag: 'b' } */
|
|
191
|
+
export const swcAppRouteLastQueryParamObject = routeParam('swcAppRouteLastQueryParamObject');
|
|
192
|
+
/** ?tag=a&tag=b → { tag: ['a', 'b'] } */
|
|
193
|
+
export const swcAppRouteQueryParamsObject = routeParam('swcAppRouteQueryParamsObject');
|
|
194
|
+
/** URLSearchParams 그대로 */
|
|
195
|
+
export const swcAppRouteURLSearchParams = routeParam('swcAppRouteURLSearchParams');
|
|
196
|
+
|
|
197
|
+
/** '/a/{id}/b/{id}' ← '/a/1/b/2' → @swcAppRoutePathVariable('id') = '1' */
|
|
198
|
+
export const swcAppRoutePathVariable = keyedRouteParam('swcAppRoutePathVariable');
|
|
199
|
+
/** = swcAppRoutePathVariable */
|
|
200
|
+
export const swcAppRouteFirstPathVariable = keyedRouteParam('swcAppRouteFirstPathVariable');
|
|
201
|
+
/** → '2' */
|
|
202
|
+
export const swcAppRouteLastPathVariable = keyedRouteParam('swcAppRouteLastPathVariable');
|
|
203
|
+
/** → ['1', '2'] */
|
|
204
|
+
export const swcAppRoutePathVariables = keyedRouteParam('swcAppRoutePathVariables');
|
|
205
|
+
/** → { id: '1' } */
|
|
206
|
+
export const swcAppRoutePathVariableObject = routeParam('swcAppRoutePathVariableObject');
|
|
207
|
+
/** = swcAppRoutePathVariableObject */
|
|
208
|
+
export const swcAppRouteFirstPathVariableObject = routeParam('swcAppRouteFirstPathVariableObject');
|
|
209
|
+
/** → { id: '2' } */
|
|
210
|
+
export const swcAppRouteLastPathVariableObject = routeParam('swcAppRouteLastPathVariableObject');
|
|
211
|
+
/** → { id: ['1', '2'] } */
|
|
212
|
+
export const swcAppRoutePathVariablesObject = routeParam('swcAppRoutePathVariablesObject');
|
|
@@ -100,7 +100,6 @@ function createPublishSwcAppMessage(messageType?: string, options?: PublishSwcAp
|
|
|
100
100
|
// 오버로드 시그니처 - 직접 사용 (괄호 없음)
|
|
101
101
|
export function publishSwcAppMessage(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
|
|
102
102
|
// 오버로드 시그니처 - 함수 호출 (괄호 있음)
|
|
103
|
-
export function publishSwcAppMessage(): MethodDecorator;
|
|
104
103
|
export function publishSwcAppMessage(messageType: string): MethodDecorator;
|
|
105
104
|
export function publishSwcAppMessage(messageType: string, options: PublishSwcAppMessageOptions): MethodDecorator;
|
|
106
105
|
export function publishSwcAppMessage(options: PublishSwcAppMessageOptions): MethodDecorator;
|
|
@@ -114,7 +113,7 @@ export function publishSwcAppMessage(targetOrMessageTypeOrOptions?: any, propert
|
|
|
114
113
|
return createPublishSwcAppMessage()(target, propertyKeyOrOptions, descriptor);
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
// 함수로 호출된 경우 (
|
|
116
|
+
// 함수로 호출된 경우 (인자 있음): @publishSwcAppMessage('messageType') / @publishSwcAppMessage({...})
|
|
118
117
|
let messageType: string | undefined;
|
|
119
118
|
let options: PublishSwcAppMessageOptions | undefined;
|
|
120
119
|
|
|
@@ -138,6 +137,6 @@ export const publishMessage = publishSwcAppMessage;
|
|
|
138
137
|
|
|
139
138
|
// Helper function to retrieve publish message metadata
|
|
140
139
|
export const getPublishSwcAppMessageMetadata = (target: any): PublishSwcAppMessageMetadata[] | undefined => {
|
|
141
|
-
const constructor = target
|
|
142
|
-
return ReflectUtils.
|
|
140
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
141
|
+
return ReflectUtils.findAllMetadata<any[]>(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor).flat();
|
|
143
142
|
};
|
package/src/decorators/query.ts
CHANGED
|
@@ -39,7 +39,7 @@ export const resolveQueryElements = (
|
|
|
39
39
|
options: QueryOptions,
|
|
40
40
|
win: Window
|
|
41
41
|
): HTMLElement[] => {
|
|
42
|
-
const hostSet = SwcUtils.getHelperAndHostSet(
|
|
42
|
+
const hostSet = SwcUtils.getHelperAndHostSet(inst);
|
|
43
43
|
let all: HTMLElement[] = [];
|
|
44
44
|
|
|
45
45
|
if (typeof selector === 'function') {
|
|
@@ -95,10 +95,11 @@ export const pickElements = (
|
|
|
95
95
|
return all.length ? all[0] : null;
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
export function query(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void;
|
|
99
98
|
export function query(selector: string, options?: QueryOptions): PropertyDecorator;
|
|
100
99
|
export function query(selector: QueryFnSelector, options?: QueryNonQueryOptions): PropertyDecorator;
|
|
101
|
-
export function query(options
|
|
100
|
+
export function query(options: QueryOptions): PropertyDecorator;
|
|
101
|
+
// bare(@query) 시그니처는 맨 뒤 — @attribute 와 같은 이유 (TS1240/TS1271)
|
|
102
|
+
export function query(target: Object, propertyKey: string | symbol): void;
|
|
102
103
|
/**
|
|
103
104
|
* @query decorator — 클래스 필드에 요소를 주입한다.
|
|
104
105
|
*
|
|
@@ -111,6 +112,10 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
111
112
|
if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
112
113
|
throw new Error(`@query decorator cannot be used on methods. (Method: ${String(optionsOrPropertyKey)})`);
|
|
113
114
|
}
|
|
115
|
+
// bare: @query — 자기 자신($this). 빈 괄호 @query() 는 타입에서 막는다 (인자가 없으면 괄호도 없다)
|
|
116
|
+
if (selectorOrTarget && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
117
|
+
return query('$this')(selectorOrTarget, optionsOrPropertyKey);
|
|
118
|
+
}
|
|
114
119
|
// With selector
|
|
115
120
|
if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
|
|
116
121
|
return (targetObj: Object, propertyKey: string | symbol, descriptor?: never): void => {
|
|
@@ -119,7 +124,7 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
const constructor = targetObj.constructor;
|
|
122
|
-
let queries = ReflectUtils.
|
|
127
|
+
let queries = ReflectUtils.getOwnMetadata(QUERY_METADATA_KEY, constructor) as QueryMetadata[] | undefined;
|
|
123
128
|
if (!queries) {
|
|
124
129
|
queries = [];
|
|
125
130
|
ReflectUtils.defineMetadata(QUERY_METADATA_KEY, queries, constructor);
|
|
@@ -157,26 +162,29 @@ export function query(selectorOrTarget?: string | ((currentThis: any, helper: He
|
|
|
157
162
|
});
|
|
158
163
|
};
|
|
159
164
|
}
|
|
160
|
-
//
|
|
165
|
+
// 옵션만: $this
|
|
161
166
|
return query('$this', selectorOrTarget as QueryOptions);
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
export const getQueryMetadata = (target: any): QueryMetadata[] => {
|
|
165
|
-
const constructor = target
|
|
166
|
-
return ReflectUtils.
|
|
170
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
171
|
+
return ReflectUtils.findAllMetadata<any[]>(QUERY_METADATA_KEY, constructor).flat();
|
|
167
172
|
};
|
|
168
173
|
|
|
169
174
|
// ─── queryAll (query의 pick:'all' 편의 래퍼 — 호환용) ───
|
|
170
175
|
export const QUERY_ALL_METADATA_KEY = QUERY_METADATA_KEY;
|
|
171
176
|
|
|
172
|
-
export function queryAll(target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): PropertyDescriptor | void;
|
|
173
177
|
export function queryAll(selector: string, options?: Omit<QueryOptions, 'pick'>): PropertyDecorator;
|
|
174
178
|
export function queryAll(selector: QueryFnSelector, options?: Omit<QueryNonQueryOptions, 'pick'>): PropertyDecorator;
|
|
175
|
-
export function queryAll(options
|
|
179
|
+
export function queryAll(options: Omit<QueryOptions, 'pick'>): PropertyDecorator;
|
|
180
|
+
export function queryAll(target: Object, propertyKey: string | symbol): void;
|
|
176
181
|
export function queryAll(selectorOrTarget?: any, optionsOrPropertyKey?: any, descriptor?: PropertyDescriptor): any {
|
|
177
|
-
// bare(필드 직접 적용)는 query로 위임
|
|
178
182
|
if (descriptor !== undefined && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
179
|
-
|
|
183
|
+
throw new Error(`@queryAll decorator cannot be used on methods. (Method: ${String(optionsOrPropertyKey)})`);
|
|
184
|
+
}
|
|
185
|
+
// bare: @queryAll — [$this]. 빈 괄호 @queryAll() 는 타입에서 막는다
|
|
186
|
+
if (selectorOrTarget && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol')) {
|
|
187
|
+
return query('$this', { pick: 'all' })(selectorOrTarget, optionsOrPropertyKey);
|
|
180
188
|
}
|
|
181
189
|
if (typeof selectorOrTarget === 'string' || typeof selectorOrTarget === 'function') {
|
|
182
190
|
return query(selectorOrTarget, {...(optionsOrPropertyKey ?? {}), pick: 'all'});
|
|
@@ -235,9 +243,9 @@ export function queryAllAll(selector: string | QueryFnSelector, options?: QueryB
|
|
|
235
243
|
* first/last/even/odd/all/number를 모두 지원하는 데코레이터를 생성한다.
|
|
236
244
|
*
|
|
237
245
|
* @example
|
|
238
|
-
* @queryIn('shadow', 'even')('.item') // shadow DOM 짝수 인덱스들
|
|
239
|
-
* @queryIn('light', 2)('.item') // light DOM 3번째 요소
|
|
240
|
-
* @queryIn('all')('.item') // root all, pick 기본 first
|
|
246
|
+
* @(queryIn('shadow', 'even')('.item')) // shadow DOM 짝수 인덱스들 (호출이 이어지면 바깥 괄호 필요)
|
|
247
|
+
* @(queryIn('light', 2)('.item')) // light DOM 3번째 요소
|
|
248
|
+
* @(queryIn('all')('.item')) // root all, pick 기본 first
|
|
241
249
|
*/
|
|
242
250
|
export const queryIn = (root: SwcRootType, pick?: QueryPick) =>
|
|
243
251
|
(selector: string | QueryFnSelector, options?: QueryBaseOptions): PropertyDecorator =>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
|
-
import { ensureInit
|
|
2
|
+
import { ensureInit } from './elementDefine';
|
|
3
3
|
import { SwcUtils } from '../utils/Utils';
|
|
4
4
|
import { ElementDefineLifeCycler, HelperHostSet } from '../types';
|
|
5
5
|
|
|
@@ -38,15 +38,7 @@ export interface RequestAnimationFrameMetadata {
|
|
|
38
38
|
*/
|
|
39
39
|
export type FrameCallback = (timestamp: number, prevValue?: any) => any;
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
const getActiveEntries = (inst: any): number[] => {
|
|
43
|
-
let entries = activeMap.get(inst);
|
|
44
|
-
if (!entries) {
|
|
45
|
-
entries = [];
|
|
46
|
-
activeMap.set(inst, entries);
|
|
47
|
-
}
|
|
48
|
-
return entries;
|
|
49
|
-
};
|
|
41
|
+
const getActiveEntries = (inst: any): number[] => (inst.__swc_requestAnimationFrameIds ??= []);
|
|
50
42
|
|
|
51
43
|
const startFrameLoop = (win: Window, entries: number[], frameFn: FrameCallback): number => {
|
|
52
44
|
let currentId = 0;
|
|
@@ -94,10 +86,9 @@ const applyRequestAnimationFrame = (options: RequestAnimationFrameOptions, targe
|
|
|
94
86
|
|
|
95
87
|
if (frameFn) {
|
|
96
88
|
ensureInit(this);
|
|
97
|
-
const
|
|
98
|
-
const win = (this as any)._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as Window);
|
|
89
|
+
const win = SwcUtils.resolveWindow(this);
|
|
99
90
|
const id = startFrameLoop(win, getActiveEntries(this), frameFn);
|
|
100
|
-
normalizedOptions.created?.(SwcUtils.getHelperAndHostSet(
|
|
91
|
+
normalizedOptions.created?.(SwcUtils.getHelperAndHostSet(this), id);
|
|
101
92
|
}
|
|
102
93
|
return res;
|
|
103
94
|
};
|
|
@@ -112,7 +103,7 @@ const applyRequestAnimationFrame = (options: RequestAnimationFrameOptions, targe
|
|
|
112
103
|
*
|
|
113
104
|
* 옵션 없이 `@requestAnimationFrame` 그대로 붙여도 되고, `@requestAnimationFrame({...})`처럼 옵션을 줄 수도 있다.
|
|
114
105
|
*/
|
|
115
|
-
export function requestAnimationFrame(options
|
|
106
|
+
export function requestAnimationFrame(options: RequestAnimationFrameOptions): MethodDecorator;
|
|
116
107
|
export function requestAnimationFrame(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
117
108
|
export function requestAnimationFrame(optionsOrTarget?: RequestAnimationFrameOptions | Object, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
118
109
|
if (propertyKey !== undefined) {
|
|
@@ -120,21 +111,21 @@ export function requestAnimationFrame(optionsOrTarget?: RequestAnimationFrameOpt
|
|
|
120
111
|
applyRequestAnimationFrame({}, optionsOrTarget as Object, propertyKey, descriptor);
|
|
121
112
|
return;
|
|
122
113
|
}
|
|
123
|
-
// 옵션과 함께: @requestAnimationFrame(
|
|
114
|
+
// 옵션과 함께: @requestAnimationFrame({...})
|
|
124
115
|
return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
|
|
125
116
|
return applyRequestAnimationFrame((optionsOrTarget as RequestAnimationFrameOptions) ?? {}, target, propertyKey, descriptor);
|
|
126
117
|
};
|
|
127
118
|
}
|
|
128
119
|
|
|
129
120
|
export const findAllRequestAnimationFrameMetadata = (target: any): RequestAnimationFrameMetadata[] => {
|
|
130
|
-
const constructor = target
|
|
121
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
131
122
|
return (ReflectUtils.findAllMetadata<RequestAnimationFrameMetadata[]>(REQUEST_ANIMATION_FRAME_METADATA_KEY, constructor) || []).flat();
|
|
132
123
|
};
|
|
133
124
|
|
|
134
125
|
export class RequestAnimationFrameLifeCycler implements ElementDefineLifeCycler {
|
|
135
126
|
onConnected(helperHostSet: HelperHostSet): void {
|
|
136
127
|
const inst = helperHostSet.$this;
|
|
137
|
-
|
|
128
|
+
inst.__swc_requestAnimationFrameIds = []; // 재연결 대비 리셋
|
|
138
129
|
const entries = getActiveEntries(inst);
|
|
139
130
|
for (const meta of findAllRequestAnimationFrameMetadata(inst)) {
|
|
140
131
|
if (meta.options.type !== 'onConnected') continue; // returnValue 타입은 수동 호출을 기다림
|
|
@@ -146,13 +137,13 @@ export class RequestAnimationFrameLifeCycler implements ElementDefineLifeCycler
|
|
|
146
137
|
|
|
147
138
|
onDisconnected(helperHostSet: HelperHostSet): void {
|
|
148
139
|
const inst = helperHostSet.$this;
|
|
149
|
-
for (const id of
|
|
140
|
+
for (const id of inst.__swc_requestAnimationFrameIds ?? []) {
|
|
150
141
|
try {
|
|
151
142
|
helperHostSet.$w.cancelAnimationFrame(id);
|
|
152
143
|
} catch (e) {
|
|
153
144
|
console.error('[SWC] cancelAnimationFrame error:', e);
|
|
154
145
|
}
|
|
155
146
|
}
|
|
156
|
-
|
|
147
|
+
inst.__swc_requestAnimationFrameIds = [];
|
|
157
148
|
}
|
|
158
149
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { ReflectUtils } from '@dooboostore/core';
|
|
2
2
|
import { SpecialSelector, SwcQueryOptions, SwcFnSelector, SwcSelector, HelperHostSet } from '../types';
|
|
3
|
+
import { buildSwcParameterArgs } from './parameter';
|
|
3
4
|
|
|
4
5
|
// 공통 옵션 — root·delegate 없음
|
|
5
6
|
export interface ResizeObserverBaseOptions {
|
|
6
7
|
box?: 'content-box' | 'border-box' | 'device-pixel-content-box';
|
|
7
|
-
|
|
8
|
+
/** 매칭 시 핸들러 실행 여부 게이트. Promise<boolean>도 되어 async 판정 가능. false면 스킵. */
|
|
9
|
+
filter?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => boolean | Promise<boolean>;
|
|
10
|
+
/** filter 통과 후 핸들러 직전 훅. await되고, 리턴값은 @resizeObserverBeforeReturn 으로 핸들러에 주입된다. */
|
|
11
|
+
before?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }) => any | Promise<any>;
|
|
12
|
+
/** 핸들러가 성공/실패해도 항상 실행되는 정리 훅. ctx로 인자/결과/에러를 받는다. 에러는 로깅됨. */
|
|
13
|
+
finally?: (matchedEls: HTMLElement[], meta: { currentThis: any, helper: HelperHostSet }, ctx: { args: any[]; result?: any; error?: any }) => any | Promise<any>;
|
|
8
14
|
removeObserver?: (target: Element, optionValue: ResizeObserverOptions) => void;
|
|
9
15
|
}
|
|
10
16
|
|
|
@@ -28,7 +34,7 @@ export const RESIZE_OBSERVER_METADATA_KEY = Symbol.for('simple-web-component:res
|
|
|
28
34
|
|
|
29
35
|
const applyResizeObserver = (selector: SwcSelector, options: ResizeObserverOptions, targetObj: Object, propertyKey: string | symbol): void => {
|
|
30
36
|
const constructor = targetObj.constructor;
|
|
31
|
-
let observers = ReflectUtils.
|
|
37
|
+
let observers = ReflectUtils.getOwnMetadata(RESIZE_OBSERVER_METADATA_KEY, constructor) as ResizeObserverMetadata[] | undefined;
|
|
32
38
|
if (!observers) {
|
|
33
39
|
observers = [];
|
|
34
40
|
ReflectUtils.defineMetadata(RESIZE_OBSERVER_METADATA_KEY, observers, constructor);
|
|
@@ -48,7 +54,7 @@ const resolveResizeObserverArgs = (
|
|
|
48
54
|
};
|
|
49
55
|
|
|
50
56
|
/**
|
|
51
|
-
* bare(@decorator)와 factory(@decorator(
|
|
57
|
+
* bare(@decorator)와 factory(@decorator(...), 빈 괄호는 타입에서 막음) 호출을 모두 처리하는 공통 디스패처.
|
|
52
58
|
* extra는 Light/Shadow/All/Delegate 변형이 강제로 덧씌우는 옵션(root, delegate 등)이다.
|
|
53
59
|
*/
|
|
54
60
|
const dispatchResizeObserver = (
|
|
@@ -62,7 +68,7 @@ const dispatchResizeObserver = (
|
|
|
62
68
|
applyResizeObserver('$this', { ...extra }, selectorOrOptionsOrTarget as Object, maybeOptionsOrPropertyKey);
|
|
63
69
|
return;
|
|
64
70
|
}
|
|
65
|
-
// 옵션과 함께: @decorator(
|
|
71
|
+
// 옵션과 함께: @decorator(selector, options) / @decorator(options)
|
|
66
72
|
const { selector, options } = resolveResizeObserverArgs(
|
|
67
73
|
selectorOrOptionsOrTarget as SwcSelector | ResizeObserverOptions | undefined,
|
|
68
74
|
maybeOptionsOrPropertyKey as ResizeObserverOptions | undefined,
|
|
@@ -76,7 +82,7 @@ const dispatchResizeObserver = (
|
|
|
76
82
|
export function resizeObserver(target: SpecialSelector, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
77
83
|
export function resizeObserver(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
78
84
|
export function resizeObserver(selector: SwcFnSelector, options?: ResizeObserverNonQueryOptions): MethodDecorator;
|
|
79
|
-
export function resizeObserver(options
|
|
85
|
+
export function resizeObserver(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
80
86
|
export function resizeObserver(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
81
87
|
/**
|
|
82
88
|
* @resizeObserver decorator to observe element size changes.
|
|
@@ -86,37 +92,32 @@ export function resizeObserver(selectorOrOptionsOrTarget?: SwcSelector | ResizeO
|
|
|
86
92
|
return dispatchResizeObserver(selectorOrOptionsOrTarget, maybeOptionsOrPropertyKey, descriptor, {});
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
export function resizeObserverThis(options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
90
|
-
export function resizeObserverThis(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
91
|
-
export function resizeObserverThis(optionsOrTarget?: ResizeObserverQueryOptions | Object, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
92
|
-
return dispatchResizeObserver(optionsOrTarget, propertyKey, descriptor, {});
|
|
93
|
-
}
|
|
94
95
|
|
|
95
96
|
// ─── root별 delegate 헬퍼 (root 주입 → 문자열 셀렉터 전용) ───
|
|
96
97
|
|
|
97
98
|
export function resizeObserverDelegateLight(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
98
|
-
export function resizeObserverDelegateLight(options
|
|
99
|
+
export function resizeObserverDelegateLight(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
99
100
|
export function resizeObserverDelegateLight(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
100
101
|
export function resizeObserverDelegateLight(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
101
102
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'light', delegate: true });
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
export function resizeObserverDelegateShadow(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
105
|
-
export function resizeObserverDelegateShadow(options
|
|
106
|
+
export function resizeObserverDelegateShadow(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
106
107
|
export function resizeObserverDelegateShadow(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
107
108
|
export function resizeObserverDelegateShadow(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
108
109
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'shadow', delegate: true });
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
export function resizeObserverDelegateAll(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
112
|
-
export function resizeObserverDelegateAll(options
|
|
113
|
+
export function resizeObserverDelegateAll(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
113
114
|
export function resizeObserverDelegateAll(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
114
115
|
export function resizeObserverDelegateAll(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
115
116
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'all', delegate: true });
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
export function resizeObserverDelegate(selector: string, options?: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
119
|
-
export function resizeObserverDelegate(options
|
|
120
|
+
export function resizeObserverDelegate(options: Omit<ResizeObserverQueryOptions, 'delegate'>): MethodDecorator;
|
|
120
121
|
export function resizeObserverDelegate(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
121
122
|
export function resizeObserverDelegate(selectorOrOptionsOrTarget?: string | Omit<ResizeObserverQueryOptions, 'delegate'> | Object, maybeOptionsOrPropertyKey?: Omit<ResizeObserverQueryOptions, 'delegate'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
122
123
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'auto', delegate: true });
|
|
@@ -125,29 +126,29 @@ export function resizeObserverDelegate(selectorOrOptionsOrTarget?: string | Omit
|
|
|
125
126
|
// ─── root별 일반 헬퍼 (delegate 없이, 셀렉터 생략 시 $this) ───
|
|
126
127
|
|
|
127
128
|
export function resizeObserverLight(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
128
|
-
export function resizeObserverLight(options
|
|
129
|
+
export function resizeObserverLight(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
129
130
|
export function resizeObserverLight(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
130
131
|
export function resizeObserverLight(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
131
132
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'light' });
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
export function resizeObserverShadow(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
135
|
-
export function resizeObserverShadow(options
|
|
136
|
+
export function resizeObserverShadow(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
136
137
|
export function resizeObserverShadow(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
137
138
|
export function resizeObserverShadow(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
138
139
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'shadow' });
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
export function resizeObserverAll(selector: string, options?: ResizeObserverQueryOptions): MethodDecorator;
|
|
142
|
-
export function resizeObserverAll(options
|
|
143
|
+
export function resizeObserverAll(options: ResizeObserverQueryOptions): MethodDecorator;
|
|
143
144
|
export function resizeObserverAll(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
|
|
144
145
|
export function resizeObserverAll(selectorOrOptionsOrTarget?: string | ResizeObserverQueryOptions | Object, maybeOptionsOrPropertyKey?: ResizeObserverQueryOptions | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | void {
|
|
145
146
|
return dispatchResizeObserver(selectorOrOptionsOrTarget as any, maybeOptionsOrPropertyKey as any, descriptor, { root: 'all' });
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
export function getResizeObserverMetadata(target: any): ResizeObserverMetadata[] | undefined {
|
|
149
|
-
const constructor = target
|
|
150
|
-
return ReflectUtils.
|
|
150
|
+
const constructor = typeof target === 'function' ? target : target.constructor;
|
|
151
|
+
return ReflectUtils.findAllMetadata<any[]>(RESIZE_OBSERVER_METADATA_KEY, constructor).flat();
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -156,20 +157,21 @@ export function getResizeObserverMetadata(target: any): ResizeObserverMetadata[]
|
|
|
156
157
|
// elementDefine 이 수집된 ResizeObserverSet 으로 observer 를 생성하고,
|
|
157
158
|
// observe/unobserve 함수를 주입해 MutationObserver delegate 추적이 사용할 수 있게 한다.
|
|
158
159
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
159
|
-
import { ElementDefineLifeCycler, OnConnectedResult, ResizeObserverSet, ResizeObserverSetEntry } from '../types';
|
|
160
|
+
import { ElementDefineLifeCycler, inObserverScope, ObserverScope, OnConnectedResult, ResizeObserverSet, ResizeObserverSetEntry } from '../types';
|
|
160
161
|
import { SwcUtils } from '../utils/Utils';
|
|
161
162
|
|
|
162
163
|
export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
163
164
|
private readonly removeObserverCallbacksMap = new WeakMap<Element, Array<{ fn: (target: Element, opts: unknown) => void; target: any; opts: unknown }>>();
|
|
164
165
|
|
|
165
|
-
onConnected(helperHostSet: HelperHostSet): OnConnectedResult | void {
|
|
166
|
+
onConnected(helperHostSet: HelperHostSet, _set?: ResizeObserverSet, scope?: ObserverScope): OnConnectedResult | void {
|
|
166
167
|
const inst = helperHostSet.$this;
|
|
167
168
|
const currentWin = helperHostSet.$w;
|
|
168
169
|
|
|
169
|
-
|
|
170
|
+
// 'rest' 는 같은 connect 의 'self' 뒤에 오므로 이어 붙이고, 그 외(새 connect)는 새로 시작한다.
|
|
171
|
+
const removeObserverCallbacks = (scope === 'rest' && this.removeObserverCallbacksMap.get(inst)) || [];
|
|
170
172
|
this.removeObserverCallbacksMap.set(inst, removeObserverCallbacks);
|
|
171
173
|
|
|
172
|
-
const allMeta = getResizeObserverMetadata(inst) ?? [];
|
|
174
|
+
const allMeta = (getResizeObserverMetadata(inst) ?? []).filter(m => inObserverScope(m, scope));
|
|
173
175
|
if (allMeta.length === 0) return;
|
|
174
176
|
|
|
175
177
|
const root: HTMLElement | ShadowRoot = inst.shadowRoot || inst;
|
|
@@ -179,6 +181,9 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
179
181
|
if (m.options.removeObserver) removeObserverCallbacks.push({ fn: m.options.removeObserver, target: root, opts: m.options });
|
|
180
182
|
}
|
|
181
183
|
|
|
184
|
+
// non-delegate 메타별 observe 대상 — 콜백은 모든 메타가 공유하므로, 엔트리를 자기 대상에만 배달한다.
|
|
185
|
+
const metaTargets = new Map<typeof allMeta[number], WeakSet<Element>>();
|
|
186
|
+
|
|
182
187
|
// ── ResizeObserver 콜백 ──
|
|
183
188
|
const callback: ResizeObserverSetEntry['callback'] = (entries, obs) => {
|
|
184
189
|
for (const m of allMeta) {
|
|
@@ -191,14 +196,29 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
191
196
|
return el.matches?.(m.selector as string) || !!el.closest?.(m.selector as string);
|
|
192
197
|
});
|
|
193
198
|
} else {
|
|
194
|
-
|
|
199
|
+
const set = metaTargets.get(m);
|
|
200
|
+
matchedEls = entries.map(e => e.target as HTMLElement).filter(t => t && t.nodeType === 1 && !!set?.has(t));
|
|
195
201
|
}
|
|
196
202
|
if (matchedEls.length === 0) continue;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
203
|
+
const opts = m.options;
|
|
204
|
+
void (async () => {
|
|
205
|
+
const helper = SwcUtils.getHelperAndHostSet(inst);
|
|
206
|
+
if (opts.filter && !(await opts.filter(matchedEls, { currentThis: inst, helper }))) return;
|
|
207
|
+
const hostSet = SwcUtils.getHostSet(inst);
|
|
208
|
+
const helperSet = SwcUtils.getHelperSet(helperHostSet.$w);
|
|
209
|
+
// entries 도 이 메서드 대상 것만 (옵저버는 공유라 배치에 다른 대상 엔트리가 섞인다)
|
|
210
|
+
const legacyArgs = [matchedEls, entries.filter(e => matchedEls.includes(e.target as HTMLElement)), obs, { ...hostSet, $root: root }];
|
|
211
|
+
const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, m.propertyKey, {
|
|
212
|
+
hostSet, helperHostSet: helper, helperSet, resizeObserverBeforeReturn: beforeReturn
|
|
213
|
+
}, [...legacyArgs, beforeReturn]);
|
|
214
|
+
let args = buildArgs(undefined);
|
|
215
|
+
if (opts.before) { const br = await opts.before(matchedEls, { currentThis: inst, helper }); args = buildArgs(br); }
|
|
216
|
+
let result: any, error: any;
|
|
217
|
+
try { result = await inst[m.propertyKey](...args); }
|
|
218
|
+
catch (e) { error = e; }
|
|
219
|
+
finally { if (opts.finally) await opts.finally(matchedEls, { currentThis: inst, helper }, { args, result, error }); }
|
|
220
|
+
if (error) throw error;
|
|
221
|
+
})().catch(e => console.error('[SWC] resizeObserver handler error:', e));
|
|
202
222
|
}
|
|
203
223
|
};
|
|
204
224
|
|
|
@@ -235,6 +255,7 @@ export class ResizeObserverLifeCycler implements ElementDefineLifeCycler {
|
|
|
235
255
|
}
|
|
236
256
|
}
|
|
237
257
|
}
|
|
258
|
+
metaTargets.set(m, new WeakSet(targets));
|
|
238
259
|
for (const el of targets) resizeObserverSet.push({ target: el, options: m.options.box ? { box: m.options.box } : undefined, callback });
|
|
239
260
|
}
|
|
240
261
|
|