@dooboostore/simple-web-component 1.0.40 → 1.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +170 -1
  2. package/dist/cjs/decorators/elementDefine.js +9 -23
  3. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  4. package/dist/cjs/decorators/lifecycles.js +78 -21
  5. package/dist/cjs/decorators/lifecycles.js.map +2 -2
  6. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +12 -4
  7. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  8. package/dist/cjs/elements/SwcAppMixin.js +9 -7
  9. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  10. package/dist/esm/decorators/elementDefine.js +9 -23
  11. package/dist/esm/decorators/elementDefine.js.map +2 -2
  12. package/dist/esm/decorators/lifecycles.js +78 -21
  13. package/dist/esm/decorators/lifecycles.js.map +2 -2
  14. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +12 -4
  15. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
  16. package/dist/esm/elements/SwcAppMixin.js +9 -7
  17. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  18. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +84 -56
  19. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +2 -2
  20. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  21. package/dist/types/decorators/lifecycles.d.ts +25 -11
  22. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  23. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +3 -1
  24. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  25. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  26. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +84 -56
  27. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +2 -2
  28. package/package.json +7 -7
  29. package/src/decorators/elementDefine.ts +9 -23
  30. package/src/decorators/lifecycles.ts +120 -26
  31. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +20 -6
  32. package/src/elements/SwcAppMixin.ts +13 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-web-component",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -67,7 +67,11 @@
67
67
  },
68
68
  "author": "dooboostore <dooboostore@gmail.com> (https://github.com/dooboostore)",
69
69
  "peerDependencies": {
70
- "reflect-metadata": "^0.2.2"
70
+ "reflect-metadata": "^0.2.2",
71
+ "@dooboostore/core": "1.0.32",
72
+ "@dooboostore/simple-boot": "1.0.56",
73
+ "@dooboostore/core-web": "1.0.12",
74
+ "@dooboostore/core-node": "1.0.12"
71
75
  },
72
76
  "devDependencies": {
73
77
  "@babel/core": "^7.24.0",
@@ -91,11 +95,7 @@
91
95
  "typescript": "^5.9.2",
92
96
  "webpack": "^5.93.0",
93
97
  "webpack-cli": "^5.1.4",
94
- "webpack-dev-server": "^5.2.0",
95
- "@dooboostore/core": "1.0.32",
96
- "@dooboostore/core-node": "1.0.12",
97
- "@dooboostore/core-web": "1.0.12",
98
- "@dooboostore/simple-boot": "1.0.56"
98
+ "webpack-dev-server": "^5.2.0"
99
99
  },
100
100
  "scripts": {
101
101
  "clean": "rm -rf dist",
@@ -128,9 +128,7 @@ export const ensureInit = (inst: any) => { // HTMLElement
128
128
 
129
129
  // Call @onInitialize lifecycle methods
130
130
  const cMethods = findAllLifecycleMetadata(inst, ON_INITIALIZE_METADATA_KEY);
131
- if (cMethods) {
132
- for (const m of cMethods) inst._invokeLifecycleMethod(m, hostSet);
133
- }
131
+ for (const m of cMethods) inst._invokeLifecycleMethod(m.propertyKey, hostSet);
134
132
  }
135
133
  };
136
134
 
@@ -387,9 +385,7 @@ export const elementDefine =
387
385
 
388
386
  const bMethods = findAllOnConnectedBeforeMetadata(this).filter(it => useSsr ? !it.options.ssrFirst : true);
389
387
  // console.log('beforeConnected', bMethods)
390
- if (bMethods) {
391
- for (const m of bMethods) await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
392
- }
388
+ for (const m of bMethods) await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
393
389
  (this as any)._executeSwcScript('swc-on-before-connected', helperHostSet);
394
390
 
395
391
  // console.log('vvvvvvvvvvvvvvvu-seSsr-vvvvvvvvvv>', useSsr, this.tagName, this.getAttribute('seq'))
@@ -603,9 +599,7 @@ export const elementDefine =
603
599
  return useSsr ? !it.options.ssrFirst : true;
604
600
  });
605
601
  // console.log('afterConnected', this.tagName, aMethods, getOnConnectedAfterMetadata(this))
606
- if (aMethods) {
607
- for (const m of aMethods) await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
608
- }
602
+ for (const m of aMethods) await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
609
603
  (this as any)._executeSwcScript('swc-on-connected', helperHostSet);
610
604
  (this as any)._executeSwcScript('swc-on-after-connected', helperHostSet);
611
605
  (this as any).__swc_connected = true;
@@ -622,8 +616,8 @@ export const elementDefine =
622
616
  }
623
617
  }
624
618
  } finally {
625
- for (let mPropertyKey of findAllLifecycleMetadata(this, ON_CONNECTED_COMPLETED_METADATA_KEY)) {
626
- await (this as any)._invokeLifecycleMethod(mPropertyKey, helperHostSet);
619
+ for (let m of findAllLifecycleMetadata(this, ON_CONNECTED_COMPLETED_METADATA_KEY)) {
620
+ await (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
627
621
  }
628
622
  if (appHost && typeof (appHost as any)._connectedDone === 'function') {
629
623
  await (appHost as any)._connectedDone(this);
@@ -643,9 +637,7 @@ export const elementDefine =
643
637
 
644
638
  (this as any)._executeSwcScript('swc-on-before-disconnected', helperHostSet);
645
639
  const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_DISCONNECTED_METADATA_KEY);
646
- if (bMethods) {
647
- for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, helperHostSet);
648
- }
640
+ for (const m of bMethods) (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
649
641
 
650
642
  if ((this as any)._boundListeners) {
651
643
  (this as any)._boundListeners.forEach((l: any) => l.target.removeEventListener(l.type, l.handler, l.options));
@@ -669,9 +661,7 @@ export const elementDefine =
669
661
  if (originalDisconnected) originalDisconnected.apply(this);
670
662
 
671
663
  const aMethods = findAllLifecycleMetadata(this, ON_AFTER_DISCONNECTED_METADATA_KEY);
672
- if (aMethods) {
673
- for (const m of aMethods) (this as any)._invokeLifecycleMethod(m, helperHostSet);
674
- }
664
+ for (const m of aMethods) (this as any)._invokeLifecycleMethod(m.propertyKey, helperHostSet);
675
665
  (this as any)._executeSwcScript('swc-on-disconnected', helperHostSet);
676
666
  (this as any)._executeSwcScript('swc-on-after-disconnected', helperHostSet);
677
667
  (this as any).__swc_connected = false;
@@ -682,16 +672,12 @@ export const elementDefine =
682
672
  const hostSet = SwcUtils.getHostSet(this as any);
683
673
  (this as any)._executeSwcScript('swc-on-before-adopted', hostSet);
684
674
  const bMethods = findAllLifecycleMetadata(this, ON_BEFORE_ADOPTED_METADATA_KEY);
685
- if (bMethods) {
686
- for (const m of bMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
687
- }
675
+ for (const m of bMethods) (this as any)._invokeLifecycleMethod(m.propertyKey, hostSet);
688
676
 
689
677
  if (originalAdopted) originalAdopted.apply(this);
690
678
 
691
679
  const aMethods = findAllLifecycleMetadata(this, ON_AFTER_ADOPTED_METADATA_KEY);
692
- if (aMethods) {
693
- for (const m of aMethods) (this as any)._invokeLifecycleMethod(m, hostSet);
694
- }
680
+ for (const m of aMethods) (this as any)._invokeLifecycleMethod(m.propertyKey, hostSet);
695
681
  (this as any)._executeSwcScript('swc-on-adopted', hostSet);
696
682
  (this as any)._executeSwcScript('swc-on-after-adopted', hostSet);
697
683
  };
@@ -26,12 +26,21 @@ export interface InnerHtmlMetadata {
26
26
 
27
27
  export interface OnConnectedOptions {
28
28
  ssrFirst?: boolean;
29
+ order?: number;
29
30
  }
30
31
  export interface OnConnectedMetadata {
31
32
  propertyKey: string | symbol;
32
33
  options: OnConnectedOptions;
33
34
  }
34
35
 
36
+ export interface LifecycleOptions {
37
+ order?: number;
38
+ }
39
+ export interface LifecycleMetadata {
40
+ propertyKey: string | symbol;
41
+ order?: number;
42
+ }
43
+
35
44
 
36
45
  export function onConnectedBefore(options: OnConnectedOptions): MethodDecorator;
37
46
  export function onConnectedBefore(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
@@ -78,35 +87,107 @@ export function onConnectedAfter(arg1?: OnConnectedOptions | Object, arg2?: stri
78
87
  }
79
88
 
80
89
 
81
- function createLifecycleDecorator(metadataKey: symbol): MethodDecorator {
82
- return (target: Object, propertyKey: string | symbol) => {
83
- const constructor = target.constructor;
84
- let list = ReflectUtils.getOwnMetadata(metadataKey, constructor) as (string | symbol)[];
85
- if (!list) {
86
- list = [];
87
- ReflectUtils.defineMetadata(metadataKey, list, constructor);
90
+ function createLifecycleDecorator(metadataKey: symbol): ((options?: LifecycleOptions) => MethodDecorator) & MethodDecorator {
91
+ const decorator = (options?: LifecycleOptions): MethodDecorator => {
92
+ return (target: Object, propertyKey: string | symbol) => {
93
+ const constructor = target.constructor;
94
+ let list = ReflectUtils.getOwnMetadata(metadataKey, constructor) as LifecycleMetadata[];
95
+ if (!list) {
96
+ list = [];
97
+ ReflectUtils.defineMetadata(metadataKey, list, constructor);
98
+ }
99
+ list.push({ propertyKey, order: options?.order ?? 0 });
100
+ };
101
+ };
102
+
103
+ // Support both @decorator and @decorator() syntax
104
+ return Object.assign(
105
+ (target: Object, propertyKey: string | symbol) => {
106
+ const constructor = target.constructor;
107
+ let list = ReflectUtils.getOwnMetadata(metadataKey, constructor) as LifecycleMetadata[];
108
+ if (!list) {
109
+ list = [];
110
+ ReflectUtils.defineMetadata(metadataKey, list, constructor);
111
+ }
112
+ list.push({ propertyKey, order: 0 });
113
+ },
114
+ { __isDecorator: true, __decorator: decorator }
115
+ ) as any;
116
+ }
117
+
118
+ // Helper to handle both @decorator and @decorator() syntax
119
+ function createLifecycleDecoratorWithOptions(metadataKey: symbol) {
120
+ return function(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
121
+ if (propertyKey) {
122
+ // Direct decorator usage: @decorator
123
+ const constructor = (optionOrTarget as Object).constructor;
124
+ let list = ReflectUtils.getOwnMetadata(metadataKey, constructor) as LifecycleMetadata[];
125
+ if (!list) {
126
+ list = [];
127
+ ReflectUtils.defineMetadata(metadataKey, list, constructor);
128
+ }
129
+ list.push({ propertyKey, order: 0 });
130
+ return;
88
131
  }
89
- list.push(propertyKey);
132
+
133
+ // Decorator with options: @decorator({ order: 1 })
134
+ return (target: Object, propertyKey: string | symbol) => {
135
+ const constructor = target.constructor;
136
+ let list = ReflectUtils.getOwnMetadata(metadataKey, constructor) as LifecycleMetadata[];
137
+ if (!list) {
138
+ list = [];
139
+ ReflectUtils.defineMetadata(metadataKey, list, constructor);
140
+ }
141
+ list.push({ propertyKey, order: (optionOrTarget as LifecycleOptions)?.order ?? 0 });
142
+ };
90
143
  };
91
144
  }
92
145
 
93
- export const onInitialize = createLifecycleDecorator(ON_INITIALIZE_METADATA_KEY);
94
- // export const onConnectedBefore = createLifecycleDecorator(ON_BEFORE_CONNECTED_METADATA_KEY);
95
- // export const onConnectedAfter = createLifecycleDecorator(ON_AFTER_CONNECTED_METADATA_KEY);
96
- // export const onConnected = onConnectedAfter;
146
+ export function onInitialize(options?: LifecycleOptions): MethodDecorator;
147
+ export function onInitialize(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
148
+ export function onInitialize(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
149
+ return createLifecycleDecoratorWithOptions(ON_INITIALIZE_METADATA_KEY)(optionOrTarget, propertyKey);
150
+ }
151
+
152
+ export function onDisconnectedBefore(options?: LifecycleOptions): MethodDecorator;
153
+ export function onDisconnectedBefore(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
154
+ export function onDisconnectedBefore(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
155
+ return createLifecycleDecoratorWithOptions(ON_BEFORE_DISCONNECTED_METADATA_KEY)(optionOrTarget, propertyKey);
156
+ }
157
+
158
+ export function onDisconnectedAfter(options?: LifecycleOptions): MethodDecorator;
159
+ export function onDisconnectedAfter(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
160
+ export function onDisconnectedAfter(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
161
+ return createLifecycleDecoratorWithOptions(ON_AFTER_DISCONNECTED_METADATA_KEY)(optionOrTarget, propertyKey);
162
+ }
97
163
 
98
- export const onDisconnectedBefore = createLifecycleDecorator(ON_BEFORE_DISCONNECTED_METADATA_KEY);
99
- export const onDisconnectedAfter = createLifecycleDecorator(ON_AFTER_DISCONNECTED_METADATA_KEY);
100
164
  export const onDisconnected = onDisconnectedAfter;
101
165
 
102
- export const onAdoptedBefore = createLifecycleDecorator(ON_BEFORE_ADOPTED_METADATA_KEY);
103
- export const onAdoptedAfter = createLifecycleDecorator(ON_AFTER_ADOPTED_METADATA_KEY);
166
+ export function onAdoptedBefore(options?: LifecycleOptions): MethodDecorator;
167
+ export function onAdoptedBefore(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
168
+ export function onAdoptedBefore(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
169
+ return createLifecycleDecoratorWithOptions(ON_BEFORE_ADOPTED_METADATA_KEY)(optionOrTarget, propertyKey);
170
+ }
171
+
172
+ export function onAdoptedAfter(options?: LifecycleOptions): MethodDecorator;
173
+ export function onAdoptedAfter(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
174
+ export function onAdoptedAfter(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
175
+ return createLifecycleDecoratorWithOptions(ON_AFTER_ADOPTED_METADATA_KEY)(optionOrTarget, propertyKey);
176
+ }
177
+
104
178
  export const onAdopted = onAdoptedAfter;
105
179
 
106
- export const onAddEventListener = createLifecycleDecorator(ON_ADD_EVENT_LISTENER_METADATA_KEY);
180
+ export function onConnectedSwcApp(options?: LifecycleOptions): MethodDecorator;
181
+ export function onConnectedSwcApp(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
182
+ export function onConnectedSwcApp(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
183
+ return createLifecycleDecoratorWithOptions(ON_CONNECTED_SWC_APP_METADATA_KEY)(optionOrTarget, propertyKey);
184
+ }
107
185
 
108
- export const onConnectedSwcApp = createLifecycleDecorator(ON_CONNECTED_SWC_APP_METADATA_KEY);
109
- export const onConnectedCompleted = createLifecycleDecorator(ON_CONNECTED_COMPLETED_METADATA_KEY);
186
+ export function onConnectedCompleted(options?: LifecycleOptions): MethodDecorator;
187
+ export function onConnectedCompleted(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): void;
188
+ export function onConnectedCompleted(optionOrTarget?: LifecycleOptions | Object, propertyKey?: string | symbol): MethodDecorator | void {
189
+ return createLifecycleDecoratorWithOptions(ON_CONNECTED_COMPLETED_METADATA_KEY)(optionOrTarget, propertyKey);
190
+ }
110
191
 
111
192
 
112
193
 
@@ -160,21 +241,34 @@ export function onConnected(optionOrTarget: InnerHtmlOptions | Object, propertyK
160
241
  /**
161
242
  * 프로토타입 체인을 순회하며 모든 라이프사이클 메서드를 수집합니다.
162
243
  */
163
- // export const findAllLifecycleMetadata = <T = (string | symbol)[]>(target: any, metadataKey: symbol): T | undefined => {
164
- export const findAllLifecycleMetadata = (target: any, metadataKey: symbol): (string | symbol)[] => {
165
- const results = ReflectUtils.findAllMetadataFlatten(metadataKey, target)??[];
166
- return results;
244
+ export const findAllLifecycleMetadata = (target: any, metadataKey: symbol): LifecycleMetadata[] => {
245
+ const constructor = target instanceof Function ? target : target.constructor;
246
+ const results = ReflectUtils.getOwnMetadata(metadataKey, constructor) as LifecycleMetadata[] ?? [];
247
+ // Sort by order (default 0 if not specified)
248
+ return [...results].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
167
249
  };
168
250
 
169
251
  export const findAllOnConnectedMetadata = (target: any): InnerHtmlMetadata[] => {
170
252
  const constructor = target instanceof Function ? target : target.constructor;
171
- return ReflectUtils.getMetadata(ON_CONNECTED_METADATA_KEY, constructor) ?? [];
253
+ const results = ReflectUtils.getMetadata(ON_CONNECTED_METADATA_KEY, constructor) ?? [];
254
+ // Sort by order (default 0 if not specified)
255
+ return [...results].sort((a, b) => {
256
+ const orderA = (a.options as any)?.order ?? 0;
257
+ const orderB = (b.options as any)?.order ?? 0;
258
+ return orderA - orderB;
259
+ });
172
260
  };
261
+
173
262
  export const findAllOnConnectedBeforeMetadata = (target: any): OnConnectedMetadata[] => {
174
263
  const constructor = target instanceof Function ? target : target.constructor;
175
- return ReflectUtils.getMetadata(ON_BEFORE_CONNECTED_METADATA_KEY, constructor) ?? [];
264
+ const results = ReflectUtils.getMetadata(ON_BEFORE_CONNECTED_METADATA_KEY, constructor) ?? [];
265
+ // Sort by order
266
+ return [...results].sort((a, b) => (a.options?.order ?? 0) - (b.options?.order ?? 0));
176
267
  };
268
+
177
269
  export const findAllOnConnectedAfterMetadata = (target: any): OnConnectedMetadata[] => {
178
270
  const constructor = target instanceof Function ? target : target.constructor;
179
- return ReflectUtils.getMetadata(ON_AFTER_CONNECTED_METADATA_KEY, constructor) ?? [];
271
+ const results = ReflectUtils.getMetadata(ON_AFTER_CONNECTED_METADATA_KEY, constructor) ?? [];
272
+ // Sort by order
273
+ return [...results].sort((a, b) => (a.options?.order ?? 0) - (b.options?.order ?? 0));
180
274
  };
@@ -14,6 +14,7 @@ export interface SwcAppRouteChangeSubscriberMetadata {
14
14
  export interface SwcAppRouteChangeOptions {
15
15
  path?: RoutePathType;
16
16
  filter?: (router: Router, meta: {currentThis: any, helper: HelperHostSet}) => boolean;
17
+ order?: number;
17
18
  }
18
19
 
19
20
  function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteChangeOptions): MethodDecorator {
@@ -38,14 +39,15 @@ export function subscribeSwcAppRouteChangeWhileConnected(target: Object, propert
38
39
  // 오버로드 시그니처 - 함수 호출 (괄호 있음)
39
40
  export function subscribeSwcAppRouteChangeWhileConnected(): MethodDecorator;
40
41
  export function subscribeSwcAppRouteChangeWhileConnected(pathPattern: RoutePathType): MethodDecorator;
42
+ export function subscribeSwcAppRouteChangeWhileConnected(pathPattern: RoutePathType, config: Omit<SwcAppRouteChangeOptions, 'path'>): MethodDecorator;
41
43
  export function subscribeSwcAppRouteChangeWhileConnected(options: SwcAppRouteChangeOptions): MethodDecorator;
42
44
 
43
45
  // 실제 구현 (이중 모드)
44
- export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
46
+ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any, propertyKeyOrConfig?: any, descriptor?: PropertyDescriptor): any {
45
47
  // 직접 데코레이터로 사용된 경우 (괄호 없음): @subscribeSwcAppRouteChangeWhileConnected
46
48
  // propertyKey가 string | symbol이고 descriptor가 있으면 직접 사용
47
- if (propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol')) {
48
- return createSubscribeSwcAppRouteChangeWhileConnected({})(targetOrOptions, propertyKey, descriptor);
49
+ if (propertyKeyOrConfig && (typeof propertyKeyOrConfig === 'string' || typeof propertyKeyOrConfig === 'symbol')) {
50
+ return createSubscribeSwcAppRouteChangeWhileConnected({})(targetOrOptions, propertyKeyOrConfig, descriptor);
49
51
  }
50
52
 
51
53
  // 함수로 호출된 경우 (괄호 있음): @subscribeSwcAppRouteChangeWhileConnected() / @subscribeSwcAppRouteChangeWhileConnected('/path')
@@ -53,12 +55,20 @@ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any,
53
55
 
54
56
  if (Array.isArray(targetOrOptions)) {
55
57
  // 배열: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'])
58
+ // 또는: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'], { order: 1 })
56
59
  options.path = targetOrOptions;
60
+ if (propertyKeyOrConfig && typeof propertyKeyOrConfig === 'object') {
61
+ options = { ...options, ...propertyKeyOrConfig };
62
+ }
57
63
  } else if (typeof targetOrOptions === 'string' || typeof targetOrOptions === 'function') {
58
64
  // 문자열 또는 함수: @subscribeSwcAppRouteChangeWhileConnected('/path')
65
+ // 또는: @subscribeSwcAppRouteChangeWhileConnected('/path', { order: 1 })
59
66
  options.path = targetOrOptions;
67
+ if (propertyKeyOrConfig && typeof propertyKeyOrConfig === 'object') {
68
+ options = { ...options, ...propertyKeyOrConfig };
69
+ }
60
70
  } else if (targetOrOptions && typeof targetOrOptions === 'object') {
61
- // 객체: @subscribeSwcAppRouteChangeWhileConnected({ path: '/path', filter: ... })
71
+ // 객체: @subscribeSwcAppRouteChangeWhileConnected({ path: '/path', filter: ..., order: 1 })
62
72
  options = targetOrOptions;
63
73
  }
64
74
 
@@ -66,7 +76,11 @@ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any,
66
76
  }
67
77
 
68
78
  // Helper function to retrieve route change subscribers metadata
69
- export const getSubscribeSwcAppRouteChangeWhileConnectedMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] | undefined => {
79
+ export const getSubscribeSwcAppRouteChangeWhileConnectedMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] => {
70
80
  const constructor = target instanceof Function ? target : target.constructor;
71
- return ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor);
81
+ const results = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor);
82
+ if (!results) return [];
83
+
84
+ // Sort by order (default 0 if not specified)
85
+ return [...results].sort((a, b) => (a.options?.order ?? 0) - (b.options?.order ?? 0));
72
86
  };
@@ -81,9 +81,12 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
81
81
 
82
82
  try {
83
83
  const routeChangeSubscribers = getSubscribeSwcAppRouteChangeWhileConnectedMetadata(instance);
84
- if (routeChangeSubscribers && Array.isArray(routeChangeSubscribers)) {
84
+ if (routeChangeSubscribers.length > 0) {
85
85
  console.log('[SWC-MIXIN] Route change subscribers found')
86
- const ps = routeChangeSubscribers.map(async metadata => {
86
+
87
+ // Subscribers are already sorted by order from getSubscribeSwcAppRouteChangeWhileConnectedMetadata
88
+ // Execute subscribers in order, stop if one returns a value
89
+ for (const metadata of routeChangeSubscribers) {
87
90
  const methodName = metadata.propertyKey;
88
91
  let pathPattern = metadata.options?.path as any;
89
92
  const filter = metadata.options?.filter;
@@ -116,10 +119,13 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
116
119
  const filterPassed = !filter || filter(this.router!, {helper:hostSet, currentThis:instance});
117
120
 
118
121
  if (pathMatched && filterPassed && instance[methodName]) {
119
- await instance[methodName]({...re, pathData: pathData});
122
+ const result = await instance[methodName]({...re, pathData: pathData});
123
+ // If handler returns a value, stop propagation to next handlers
124
+ if (result !== undefined && result !== null) {
125
+ break;
126
+ }
120
127
  }
121
- });
122
- await Promise.allSettled(ps);
128
+ }
123
129
  }
124
130
  } finally {
125
131
  if (this.config?.ssr) {
@@ -144,9 +150,9 @@ export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base
144
150
  }
145
151
  this._swc_connected_instance.add(instance);
146
152
 
147
- const connectedSwcAppCallBacks = findAllLifecycleMetadata(instance, ON_CONNECTED_SWC_APP_METADATA_KEY) ?? [];
153
+ const connectedSwcAppCallBacks = findAllLifecycleMetadata(instance, ON_CONNECTED_SWC_APP_METADATA_KEY);
148
154
  for (let connectedSwcAppCallBack of connectedSwcAppCallBacks) {
149
- await (instance as any)?._invokeLifecycleMethod?.(connectedSwcAppCallBack);
155
+ await (instance as any)?._invokeLifecycleMethod?.(connectedSwcAppCallBack.propertyKey);
150
156
  }
151
157
 
152
158
  if (this._childrenConnectedDoneInterval) {