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