@dooboostore/simple-web-component 1.0.31 → 1.0.33

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 (100) hide show
  1. package/README.md +280 -43
  2. package/dist/cjs/decorators/applyStyle.js +1 -1
  3. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  4. package/dist/cjs/decorators/attribute.js +17 -1
  5. package/dist/cjs/decorators/attribute.js.map +2 -2
  6. package/dist/cjs/decorators/elementDefine.js +27 -10
  7. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  8. package/dist/cjs/decorators/index.js +3 -1
  9. package/dist/cjs/decorators/index.js.map +2 -2
  10. package/dist/cjs/decorators/publishSwcAppMessage.js +86 -0
  11. package/dist/cjs/decorators/publishSwcAppMessage.js.map +7 -0
  12. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js +62 -0
  13. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
  14. package/dist/cjs/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +16 -16
  15. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
  16. package/dist/cjs/elements/SwcAppMixin.js +32 -3
  17. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  18. package/dist/cjs/elements/SwcAsync.js +69 -57
  19. package/dist/cjs/elements/SwcAsync.js.map +2 -2
  20. package/dist/cjs/elements/SwcChoose.js +66 -60
  21. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  22. package/dist/cjs/elements/SwcIf.js +51 -66
  23. package/dist/cjs/elements/SwcIf.js.map +2 -2
  24. package/dist/cjs/elements/SwcLoop.js +58 -78
  25. package/dist/cjs/elements/SwcLoop.js.map +2 -2
  26. package/dist/cjs/elements/register.js +310 -335
  27. package/dist/cjs/elements/register.js.map +2 -2
  28. package/dist/cjs/types.js.map +1 -1
  29. package/dist/cjs/utils/Utils.js +7 -13
  30. package/dist/cjs/utils/Utils.js.map +2 -2
  31. package/dist/esm/decorators/applyStyle.js +1 -1
  32. package/dist/esm/decorators/applyStyle.js.map +2 -2
  33. package/dist/esm/decorators/attribute.js +18 -2
  34. package/dist/esm/decorators/attribute.js.map +2 -2
  35. package/dist/esm/decorators/elementDefine.js +25 -8
  36. package/dist/esm/decorators/elementDefine.js.map +3 -3
  37. package/dist/esm/decorators/index.js +3 -1
  38. package/dist/esm/decorators/index.js.map +2 -2
  39. package/dist/esm/decorators/publishSwcAppMessage.js +67 -0
  40. package/dist/esm/decorators/publishSwcAppMessage.js.map +7 -0
  41. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +43 -0
  42. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +7 -0
  43. package/dist/esm/decorators/{subscribeSwcAppRouteChange.js → subscribeSwcAppRouteChangeWhileConnected.js} +13 -13
  44. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +7 -0
  45. package/dist/esm/elements/SwcAppMixin.js +32 -3
  46. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  47. package/dist/esm/elements/SwcAsync.js +70 -58
  48. package/dist/esm/elements/SwcAsync.js.map +2 -2
  49. package/dist/esm/elements/SwcChoose.js +67 -61
  50. package/dist/esm/elements/SwcChoose.js.map +2 -2
  51. package/dist/esm/elements/SwcIf.js +52 -67
  52. package/dist/esm/elements/SwcIf.js.map +2 -2
  53. package/dist/esm/elements/SwcLoop.js +59 -79
  54. package/dist/esm/elements/SwcLoop.js.map +2 -2
  55. package/dist/esm/elements/register.js +239 -264
  56. package/dist/esm/elements/register.js.map +2 -2
  57. package/dist/esm/types.js.map +1 -1
  58. package/dist/esm/utils/Utils.js +7 -13
  59. package/dist/esm/utils/Utils.js.map +2 -2
  60. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +2804 -2498
  61. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  62. package/dist/types/decorators/attribute.d.ts.map +1 -1
  63. package/dist/types/decorators/elementDefine.d.ts +1 -0
  64. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  65. package/dist/types/decorators/index.d.ts +3 -1
  66. package/dist/types/decorators/index.d.ts.map +1 -1
  67. package/dist/types/decorators/publishSwcAppMessage.d.ts +13 -0
  68. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -0
  69. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +16 -0
  70. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -0
  71. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +18 -0
  72. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -0
  73. package/dist/types/elements/SwcAppMixin.d.ts +3 -0
  74. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  75. package/dist/types/elements/register.d.ts.map +1 -1
  76. package/dist/types/types.d.ts +14 -1
  77. package/dist/types/types.d.ts.map +1 -1
  78. package/dist/types/utils/Utils.d.ts.map +1 -1
  79. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +2804 -2498
  80. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  81. package/package.json +4 -4
  82. package/src/decorators/applyStyle.ts +1 -1
  83. package/src/decorators/attribute.ts +35 -30
  84. package/src/decorators/elementDefine.ts +28 -8
  85. package/src/decorators/index.ts +3 -1
  86. package/src/decorators/publishSwcAppMessage.ts +100 -0
  87. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +73 -0
  88. package/src/decorators/{subscribeSwcAppRouteChange.ts → subscribeSwcAppRouteChangeWhileConnected.ts} +19 -19
  89. package/src/elements/SwcAppMixin.ts +43 -4
  90. package/src/elements/SwcAsync.ts +75 -69
  91. package/src/elements/SwcChoose.ts +67 -80
  92. package/src/elements/SwcIf.ts +51 -76
  93. package/src/elements/SwcLoop.ts +56 -87
  94. package/src/elements/register.ts +235 -307
  95. package/src/types.ts +14 -1
  96. package/src/utils/Utils.ts +11 -17
  97. package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +0 -7
  98. package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +0 -7
  99. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +0 -18
  100. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-web-component",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -92,10 +92,10 @@
92
92
  "webpack": "^5.93.0",
93
93
  "webpack-cli": "^5.1.4",
94
94
  "webpack-dev-server": "^5.2.0",
95
- "@dooboostore/core": "1.0.30",
96
- "@dooboostore/core-node": "1.0.12",
97
95
  "@dooboostore/core-web": "1.0.10",
98
- "@dooboostore/simple-boot": "1.0.54"
96
+ "@dooboostore/core": "1.0.30",
97
+ "@dooboostore/simple-boot": "1.0.54",
98
+ "@dooboostore/core-node": "1.0.12"
99
99
  },
100
100
  "scripts": {
101
101
  "clean": "rm -rf dist",
@@ -34,7 +34,7 @@ function createStyleDecorator(action: StyleAction) {
34
34
  if (res !== undefined) {
35
35
  const win = (this as any).ownerDocument?.defaultView || window;
36
36
  const host = this as unknown as HTMLElement;
37
- const hostSet = { ...SwcUtils.getHelperAndHostSet(win, host), $this: this };
37
+ const hostSet = SwcUtils.getHelperAndHostSet(win, host);
38
38
  const r = options.root || 'auto';
39
39
  const targetEls: HTMLElement[] = [];
40
40
 
@@ -1,7 +1,8 @@
1
- import {ReflectUtils} from '@dooboostore/core';
1
+ import {ReflectUtils, FunctionUtils, ActionExpression} from '@dooboostore/core';
2
2
  import {ensureInit, getElementConfig} from './elementDefine';
3
3
  import {SwcUtils} from '../utils/Utils';
4
4
  import {SpecialSelector, SwcQueryOptions} from '../types';
5
+ import { ConvertUtils } from '@dooboostore/core-web';
5
6
  export interface AttributeFieldOptions extends SwcQueryOptions {
6
7
  name?: string;
7
8
  // connectedInitialize?: boolean;
@@ -113,38 +114,42 @@ export function attribute(selector: string, options: AttributeFieldOptions = {})
113
114
 
114
115
  Object.defineProperty(target, propertyKey, {
115
116
  get(this: any) {
116
- // console.log('------>??gettttt', this, propertyKey);
117
- // try {
118
- const attrName = options.name || String(propertyKey);
119
- const conf = getElementConfig(this);
120
- const currentWin = this._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as any);
121
- const targetType = options.type || designType;
122
- //
123
- // connectedInitialize: true이면 privateKey 값만 반환 (DOM 무시)
124
- // if (options.connectedInitialize === true && (this as any).__swc_syncing_init) {
125
- // console.log('cccccccc2');
126
- // return this[privateKey];
127
- // // return convertValue(this[privateKey], targetType);
128
- // }
129
-
130
- const targets = resolveTargetEls(this, selector, options, currentWin);
131
- const primaryTarget = targets[0];
132
-
133
- if (primaryTarget && typeof (primaryTarget as any).hasAttribute === 'function') {
134
- if ((primaryTarget as any).hasAttribute(attrName)) {
135
- const domVal = (primaryTarget as any).getAttribute(attrName);
136
- return convertValue(domVal, targetType);
117
+ const attrName = options.name || String(propertyKey);
118
+ const conf = getElementConfig(this);
119
+ const currentWin = this._resolveWindow?.(conf) || ((typeof window !== 'undefined' ? window : undefined) as any);
120
+ const targetType = options.type || designType;
121
+
122
+ const targets = resolveTargetEls(this, selector, options, currentWin);
123
+ const primaryTarget = targets[0];
124
+
125
+ if (primaryTarget && typeof (primaryTarget as any).hasAttribute === 'function') {
126
+ if ((primaryTarget as any).hasAttribute(attrName)) {
127
+ let domVal = (primaryTarget as any).getAttribute(attrName);
128
+
129
+ // 표현식 체크
130
+ const ae = new ActionExpression(domVal);
131
+ const expr = ae.getFirstExpression('call-return');
132
+ if (expr) {
133
+ try {
134
+ const result = FunctionUtils.executeReturn({
135
+ script: ConvertUtils.decodeHtmlEntity(expr.script, currentWin.document),
136
+ context: this,
137
+ args: SwcUtils.getHelperAndHostSet(currentWin, this)
138
+ });
139
+ return convertValue(result, targetType);
140
+ } catch (e) {
141
+ console.error(`[SWC] Failed to execute directive {{= ${expr.script} }}:`, e);
142
+ return convertValue(domVal, targetType);
143
+ }
137
144
  }
138
- return null;
145
+
146
+ return convertValue(domVal, targetType);
139
147
  }
148
+ return null;
149
+ }
140
150
 
141
- const data = convertValue(this[privateKey], targetType);
142
- // console.log('get rrr', data);
143
- return data;
144
- // } catch (err) {
145
- // console.error('Error in getter:', err);
146
- // throw err;
147
- // }
151
+ const data = convertValue(this[privateKey], targetType);
152
+ return data;
148
153
  },
149
154
  set(this: any, nv: any) {
150
155
  // this[propertyKey] = nv;
@@ -1,5 +1,4 @@
1
- import { ReflectUtils } from '@dooboostore/core';
2
- import { FunctionUtils } from '@dooboostore/core';
1
+ import { ReflectUtils, FunctionUtils, ActionExpression } from '@dooboostore/core';
3
2
  import { getAddEventListenerMetadata } from './addEventListener';
4
3
  import { ON_INITIALIZE_METADATA_KEY, ON_BEFORE_CONNECTED_METADATA_KEY, ON_AFTER_CONNECTED_METADATA_KEY, ON_BEFORE_DISCONNECTED_METADATA_KEY, ON_AFTER_DISCONNECTED_METADATA_KEY, ON_BEFORE_ADOPTED_METADATA_KEY, ON_AFTER_ADOPTED_METADATA_KEY, findAllLifecycleMetadata, getOnConnectedInnerHtmlMetadata } from './lifecycles';
5
4
  import { getEmitCustomEventMetadataList } from './emitCustomEvent';
@@ -12,6 +11,7 @@ import { SwcUtils } from '../utils/Utils';
12
11
  import { HTML_TAG_ENTRIES, DOM_EVENT_NAMES } from '../config/config';
13
12
  import { SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';
14
13
  import { InjectSituationType, HostSet } from '../types';
14
+ import { ConvertUtils } from '@dooboostore/core-web';
15
15
 
16
16
  // --- Core Interfaces & Types ---
17
17
 
@@ -22,6 +22,7 @@ export interface ElementConfig {
22
22
  observedAttributes?: string[];
23
23
  customElementRegistry?: any;
24
24
  window?: Window;
25
+ useShadow?: boolean;
25
26
  }
26
27
 
27
28
  export interface ElementMetadata extends Omit<ElementConfig, 'window'> {
@@ -214,8 +215,7 @@ const setupPrototype = (proto: any) => {
214
215
  if (oldHandler) el.removeEventListener(eventName, oldHandler);
215
216
 
216
217
  const handler = async (event: any) => {
217
- const parent = SwcUtils.findNearestSwcHost(el);
218
- const hostSet = SwcUtils.getHostSet(parent || el);
218
+ const hostSet = SwcUtils.getHostSet(el);
219
219
  const conf = getElementConfig(this);
220
220
  const currentWin = (this as any)._resolveWindow(conf);
221
221
  const helpers = SwcUtils.getHelperSet(currentWin);
@@ -237,8 +237,7 @@ const setupPrototype = (proto: any) => {
237
237
  proto.__swc_executeAttributeEvent = async function (el: HTMLElement, attrName: string, script: string, event: Event) {
238
238
  ensureInit(this);
239
239
 
240
- const parent = SwcUtils.findNearestSwcHost(el);
241
- const hostSet = SwcUtils.getHostSet(parent || el);
240
+ const hostSet = SwcUtils.getHostSet(el);
242
241
  const conf = getElementConfig(this);
243
242
  const currentWin = (this as any)._resolveWindow(conf);
244
243
  const currentHelpers = SwcUtils.getHelperSet(currentWin);
@@ -318,7 +317,7 @@ export const elementDefine =
318
317
  const conf = getElementConfig(this);
319
318
  const currentWin = (this as any)._resolveWindow(conf);
320
319
 
321
- if (connectedInnerHtmlList.some(it => it.options.useShadow === true) && !this.shadowRoot) {
320
+ if ((connectedInnerHtmlList.some(it => it.options.useShadow === true) || conf?.useShadow === true) && !this.shadowRoot) {
322
321
  this.attachShadow({ mode: 'open' });
323
322
  }
324
323
 
@@ -565,6 +564,27 @@ export const elementDefine =
565
564
 
566
565
  const hSet = SwcUtils.getHostSet(this as any);
567
566
 
567
+ // Process expression directive before passing to handlers
568
+ let processedVal = newVal;
569
+ if (newVal !== null) {
570
+ const ae = new ActionExpression(newVal);
571
+ const expr = ae.getFirstExpression('call-return');
572
+ if (expr) {
573
+ const win = (this as any)._resolveWindow?.() || ((typeof window !== 'undefined' ? window : undefined) as any);
574
+ try {
575
+ const result = FunctionUtils.executeReturn({
576
+ script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
577
+ context: this,
578
+ args: SwcUtils.getHelperAndHostSet(win,this as any)
579
+ });
580
+ processedVal = String(result);
581
+ } catch (e) {
582
+ console.error(`[SWC] Failed to execute directive {{= ${expr.script} }} on attribute ${name}:`, e);
583
+ processedVal = newVal;
584
+ }
585
+ }
586
+ }
587
+
568
588
  if (name.startsWith('swc-on-') && !swcLifecycleAttributes.includes(name)) {
569
589
  if (newVal !== null) {
570
590
  const eventName = name.substring(7);
@@ -579,7 +599,7 @@ export const elementDefine =
579
599
 
580
600
  const mKeys = attrChangeMap.get(name);
581
601
  if (mKeys && Array.isArray(mKeys)) {
582
- for (const key of mKeys) (this as any)[key](newVal, old, name, hSet);
602
+ for (const key of mKeys) (this as any)[key](processedVal, old, name, hSet);
583
603
  }
584
604
  };
585
605
 
@@ -11,4 +11,6 @@ export * from './applyClass';
11
11
  export * from './applyStyle';
12
12
  export * from './applyAttribute';
13
13
  export * from './setProperty';
14
- export * from './subscribeSwcAppRouteChange';
14
+ export * from './subscribeSwcAppRouteChangeWhileConnected';
15
+ export * from './subscribeSwcAppMessageWhileConnected';
16
+ export * from './publishSwcAppMessage';
@@ -0,0 +1,100 @@
1
+ import { ReflectUtils } from '@dooboostore/core';
2
+ import { SwcAppMessage } from '../types';
3
+ import { SwcUtils } from '../utils/Utils';
4
+
5
+ export const PUBLISH_SWC_APP_MESSAGE_METADATA_KEY = Symbol.for('simple-web-component:publish-swc-app-message');
6
+
7
+ export interface PublishSwcAppMessageMetadata {
8
+ propertyKey: string | symbol;
9
+ messageType?: string;
10
+ }
11
+
12
+ export interface PublishSwcAppMessageOptions {
13
+ messageType?: string;
14
+ }
15
+
16
+ function createPublishSwcAppMessage(messageType?: string): MethodDecorator {
17
+ return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
18
+ const constructor = target.constructor;
19
+ let list = ReflectUtils.getOwnMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor) as PublishSwcAppMessageMetadata[];
20
+ if (!list) {
21
+ list = [];
22
+ ReflectUtils.defineMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, list, constructor);
23
+ }
24
+ list.push({ propertyKey, messageType });
25
+
26
+ if (!descriptor) {
27
+ return descriptor;
28
+ }
29
+
30
+ // 메서드 래핑 - 원본 메서드의 반환값을 캡처하여 메시지 발행
31
+ const originalMethod = descriptor.value;
32
+ descriptor.value = function (...args: any[]) {
33
+ // 원본 메서드 실행
34
+ const result = originalMethod.apply(this, args);
35
+
36
+ // Promise 체크
37
+ if (result instanceof Promise) {
38
+ result.then((data) => {
39
+ // appHost 찾아서 메시지 발행
40
+ const appHost = SwcUtils.getAppHost(this as HTMLElement);
41
+ if (appHost) {
42
+ appHost.publishMessage({
43
+ publisher: this,
44
+ data,
45
+ type: messageType
46
+ });
47
+ }
48
+ }).catch((err) => {
49
+ console.warn('publishSwcAppMessage async error:', err);
50
+ });
51
+ } else {
52
+ // 동기 호출 - 바로 메시지 발행
53
+ const appHost = SwcUtils.getAppHost(this as HTMLElement);
54
+ if (appHost) {
55
+ appHost.publishMessage({
56
+ publisher: this,
57
+ data: result,
58
+ type: messageType
59
+ });
60
+ }
61
+ }
62
+
63
+ return result;
64
+ };
65
+
66
+ return descriptor;
67
+ };
68
+ }
69
+
70
+ // 오버로드 시그니처 - 직접 사용 (괄호 없음)
71
+ export function publishSwcAppMessage(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
72
+ // 오버로드 시그니처 - 함수 호출 (괄호 있음)
73
+ export function publishSwcAppMessage(): MethodDecorator;
74
+ export function publishSwcAppMessage(messageType: string): MethodDecorator;
75
+
76
+ export function publishSwcAppMessage(targetOrMessageType?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
77
+ // 직접 데코레이터로 사용된 경우 (괄호 없음): @publishSwcAppMessage
78
+ if (targetOrMessageType && typeof targetOrMessageType === 'object' &&
79
+ propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol') &&
80
+ descriptor) {
81
+ const target = targetOrMessageType;
82
+ return createPublishSwcAppMessage()(target, propertyKey, descriptor);
83
+ }
84
+
85
+ // 함수로 호출된 경우 (괄호 있음): @publishSwcAppMessage() / @publishSwcAppMessage('messageType')
86
+ let messageType: string | undefined;
87
+
88
+ if (typeof targetOrMessageType === 'string') {
89
+ // 메시지 타입 전달: @publishSwcAppMessage('messageType')
90
+ messageType = targetOrMessageType;
91
+ }
92
+
93
+ return createPublishSwcAppMessage(messageType);
94
+ }
95
+
96
+ // Helper function to retrieve publish message metadata
97
+ export const getPublishSwcAppMessageMetadata = (target: any): PublishSwcAppMessageMetadata[] | undefined => {
98
+ const constructor = target instanceof Function ? target : target.constructor;
99
+ return ReflectUtils.getOwnMetadata(PUBLISH_SWC_APP_MESSAGE_METADATA_KEY, constructor);
100
+ };
@@ -0,0 +1,73 @@
1
+ import { ReflectUtils } from '@dooboostore/core';
2
+ import { SwcAppMessage } from '../types';
3
+
4
+ export const SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY = Symbol.for('simple-web-component:subscribe-swc-app-message-while-connected');
5
+
6
+ export interface SwcAppMessageSubscriberMetadata {
7
+ propertyKey: string | symbol;
8
+ messageType?: string;
9
+ filter?: (message: SwcAppMessage) => boolean;
10
+ }
11
+
12
+ export interface SwcAppMessageOptions {
13
+ filter?: (message: SwcAppMessage) => boolean;
14
+ }
15
+
16
+ function createSubscribeSwcAppMessageWhileConnected(options?: SwcAppMessageOptions, messageType?: string): MethodDecorator {
17
+ return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
18
+ const filter = options?.filter;
19
+
20
+ const constructor = target.constructor;
21
+ let list = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, constructor) as SwcAppMessageSubscriberMetadata[];
22
+ if (!list) {
23
+ list = [];
24
+ ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, list, constructor);
25
+ }
26
+ list.push({ propertyKey, messageType, filter });
27
+
28
+ return descriptor;
29
+ };
30
+ }
31
+
32
+ // 오버로드 시그니처 - 직접 사용 (괄호 없음)
33
+ export function subscribeSwcAppMessageWhileConnected(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
34
+ // 오버로드 시그니처 - 함수 호출 (괄호 있음) - 메시지 타입만
35
+ export function subscribeSwcAppMessageWhileConnected(messageType: string): MethodDecorator;
36
+ // 오버로드 시그니처 - 함수 호출 (괄호 있음) - 옵션만
37
+ export function subscribeSwcAppMessageWhileConnected(options: SwcAppMessageOptions): MethodDecorator;
38
+ // 오버로드 시그니처 - 함수 호출 (괄호 있음) - 메시지 타입 + 옵션
39
+ export function subscribeSwcAppMessageWhileConnected(messageType: string, options: SwcAppMessageOptions): MethodDecorator;
40
+
41
+ export function subscribeSwcAppMessageWhileConnected(targetOrMessageTypeOrOptions?: any, optionsOrPropertyKey?: any, descriptor?: PropertyDescriptor): any {
42
+ // 직접 데코레이터로 사용된 경우 (괄호 없음): @subscribeSwcAppMessageWhileConnected
43
+ if (targetOrMessageTypeOrOptions && typeof targetOrMessageTypeOrOptions === 'object' &&
44
+ optionsOrPropertyKey && (typeof optionsOrPropertyKey === 'string' || typeof optionsOrPropertyKey === 'symbol') &&
45
+ descriptor) {
46
+ const target = targetOrMessageTypeOrOptions;
47
+ const propertyKey = optionsOrPropertyKey;
48
+ return createSubscribeSwcAppMessageWhileConnected({})(target, propertyKey, descriptor);
49
+ }
50
+
51
+ // 함수로 호출된 경우 (괄호 있음)
52
+ let messageType: string | undefined;
53
+ let options: SwcAppMessageOptions = {};
54
+
55
+ if (typeof targetOrMessageTypeOrOptions === 'string') {
56
+ // 메시지 타입 전달: @subscribeSwcAppMessageWhileConnected('messageType') 또는 @subscribeSwcAppMessageWhileConnected('messageType', options)
57
+ messageType = targetOrMessageTypeOrOptions;
58
+ if (optionsOrPropertyKey && typeof optionsOrPropertyKey === 'object') {
59
+ options = optionsOrPropertyKey;
60
+ }
61
+ } else if (targetOrMessageTypeOrOptions && typeof targetOrMessageTypeOrOptions === 'object') {
62
+ // 옵션만 전달: @subscribeSwcAppMessageWhileConnected({ filter: ... })
63
+ options = targetOrMessageTypeOrOptions;
64
+ }
65
+
66
+ return createSubscribeSwcAppMessageWhileConnected(options, messageType);
67
+ }
68
+
69
+ // Helper function to retrieve message subscribers metadata
70
+ export const getSubscribeSwcAppMessageWhileConnectedMetadata = (target: any): SwcAppMessageSubscriberMetadata[] | undefined => {
71
+ const constructor = target instanceof Function ? target : target.constructor;
72
+ return ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_MESSAGE_WHILE_CONNECTED_METADATA_KEY, constructor);
73
+ };
@@ -1,7 +1,7 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { Router } from '@dooboostore/core-web';
3
3
 
4
- export const SUBSCRIBE_SWC_APP_ROUTE_CHANGE_METADATA_KEY = Symbol.for('simple-web-component:subscribe-swc-app-route-change');
4
+ export const SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY = Symbol.for('simple-web-component:subscribe-swc-app-route-change-while-connected');
5
5
 
6
6
  export interface SwcAppRouteChangeSubscriberMetadata {
7
7
  propertyKey: string | symbol;
@@ -14,16 +14,16 @@ export interface SwcAppRouteChangeOptions {
14
14
  filter?: (router: Router) => boolean;
15
15
  }
16
16
 
17
- function createSwcAppRouteChangeSubscriber(options?: SwcAppRouteChangeOptions): MethodDecorator {
17
+ function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteChangeOptions): MethodDecorator {
18
18
  return (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => {
19
19
  const pathPattern = options?.path;
20
20
  const filter = options?.filter;
21
21
 
22
22
  const constructor = target.constructor;
23
- let list = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_METADATA_KEY, constructor) as SwcAppRouteChangeSubscriberMetadata[];
23
+ let list = ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor) as SwcAppRouteChangeSubscriberMetadata[];
24
24
  if (!list) {
25
25
  list = [];
26
- ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_METADATA_KEY, list, constructor);
26
+ ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, list, constructor);
27
27
  }
28
28
  list.push({ propertyKey, pathPattern, filter });
29
29
 
@@ -32,40 +32,40 @@ function createSwcAppRouteChangeSubscriber(options?: SwcAppRouteChangeOptions):
32
32
  }
33
33
 
34
34
  // 오버로드 시그니처 - 직접 사용 (괄호 없음)
35
- export function subscribeSwcAppRouteChange(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
35
+ export function subscribeSwcAppRouteChangeWhileConnected(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
36
36
  // 오버로드 시그니처 - 함수 호출 (괄호 있음)
37
- export function subscribeSwcAppRouteChange(): MethodDecorator;
38
- export function subscribeSwcAppRouteChange(pathPattern: string): MethodDecorator;
39
- export function subscribeSwcAppRouteChange(pathPatterns: string[]): MethodDecorator;
40
- export function subscribeSwcAppRouteChange(options: SwcAppRouteChangeOptions): MethodDecorator;
37
+ export function subscribeSwcAppRouteChangeWhileConnected(): MethodDecorator;
38
+ export function subscribeSwcAppRouteChangeWhileConnected(pathPattern: string): MethodDecorator;
39
+ export function subscribeSwcAppRouteChangeWhileConnected(pathPatterns: string[]): MethodDecorator;
40
+ export function subscribeSwcAppRouteChangeWhileConnected(options: SwcAppRouteChangeOptions): MethodDecorator;
41
41
 
42
42
  // 실제 구현 (이중 모드)
43
- export function subscribeSwcAppRouteChange(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
44
- // 직접 데코레이터로 사용된 경우 (괄호 없음): @subscribeSwcAppRouteChange
43
+ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any, propertyKey?: string | symbol, descriptor?: PropertyDescriptor): any {
44
+ // 직접 데코레이터로 사용된 경우 (괄호 없음): @subscribeSwcAppRouteChangeWhileConnected
45
45
  // propertyKey가 string | symbol이고 descriptor가 있으면 직접 사용
46
46
  if (propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol')) {
47
- return createSwcAppRouteChangeSubscriber({})(targetOrOptions, propertyKey, descriptor);
47
+ return createSubscribeSwcAppRouteChangeWhileConnected({})(targetOrOptions, propertyKey, descriptor);
48
48
  }
49
49
 
50
- // 함수로 호출된 경우 (괄호 있음): @subscribeSwcAppRouteChange() / @subscribeSwcAppRouteChange('/path')
50
+ // 함수로 호출된 경우 (괄호 있음): @subscribeSwcAppRouteChangeWhileConnected() / @subscribeSwcAppRouteChangeWhileConnected('/path')
51
51
  let options: SwcAppRouteChangeOptions = {};
52
52
 
53
53
  if (Array.isArray(targetOrOptions)) {
54
- // 배열: @subscribeSwcAppRouteChange(['/path1', '/path2'])
54
+ // 배열: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'])
55
55
  options.path = targetOrOptions;
56
56
  } else if (typeof targetOrOptions === 'string') {
57
- // 문자열: @subscribeSwcAppRouteChange('/path')
57
+ // 문자열: @subscribeSwcAppRouteChangeWhileConnected('/path')
58
58
  options.path = targetOrOptions;
59
59
  } else if (targetOrOptions && typeof targetOrOptions === 'object') {
60
- // 객체: @subscribeSwcAppRouteChange({ path: '/path', filter: ... })
60
+ // 객체: @subscribeSwcAppRouteChangeWhileConnected({ path: '/path', filter: ... })
61
61
  options = targetOrOptions;
62
62
  }
63
63
 
64
- return createSwcAppRouteChangeSubscriber(options);
64
+ return createSubscribeSwcAppRouteChangeWhileConnected(options);
65
65
  }
66
66
 
67
67
  // Helper function to retrieve route change subscribers metadata
68
- export const getSubscribeSwcAppRouteChangeMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] | undefined => {
68
+ export const getSubscribeSwcAppRouteChangeWhileConnectedMetadata = (target: any): SwcAppRouteChangeSubscriberMetadata[] | undefined => {
69
69
  const constructor = target instanceof Function ? target : target.constructor;
70
- return ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_METADATA_KEY, constructor);
70
+ return ReflectUtils.getOwnMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, constructor);
71
71
  };
@@ -1,10 +1,11 @@
1
1
  import { SwcAppEngine, SwcAttributeConfigType, SwcConfigType } from './SwcAppEngine';
2
- import { SwcAppInterface } from '../types';
2
+ import { SwcAppInterface, SwcAppMessage } from '../types';
3
3
  import { SwcUtils } from '../utils/Utils';
4
4
  import { FunctionUtils, Subscription } from '@dooboostore/core';
5
5
  import { Router, RouterEventType } from '@dooboostore/core-web';
6
6
  import { ON_CONNECTED_SWC_APP_METADATA_KEY, findAllLifecycleMetadata } from '../decorators/lifecycles';
7
- import { getSubscribeSwcAppRouteChangeMetadata } from '../decorators/subscribeSwcAppRouteChange';
7
+ import { getSubscribeSwcAppRouteChangeWhileConnectedMetadata } from '../decorators/subscribeSwcAppRouteChangeWhileConnected';
8
+ import { getSubscribeSwcAppMessageWhileConnectedMetadata } from '../decorators/subscribeSwcAppMessageWhileConnected';
8
9
 
9
10
  export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Base: T) {
10
11
  //@ts-ignore
@@ -29,7 +30,7 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
29
30
  }
30
31
 
31
32
  _invokeRouteChangeSubscribers(instance: any, re: RouterEventType) {
32
- const routeChangeSubscribers = getSubscribeSwcAppRouteChangeMetadata(instance);
33
+ const routeChangeSubscribers = getSubscribeSwcAppRouteChangeWhileConnectedMetadata(instance);
33
34
  if (routeChangeSubscribers && Array.isArray(routeChangeSubscribers)) {
34
35
  routeChangeSubscribers.forEach((metadata: any) => {
35
36
  const methodName = metadata.propertyKey || metadata;
@@ -185,7 +186,7 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
185
186
  const userConfig = FunctionUtils.executeReturn({
186
187
  script: configStr,
187
188
  context: this,
188
- args: SwcUtils.getHelperAndHostSet(win, SwcUtils.findNearestSwcHost(this))
189
+ args: SwcUtils.getHelperAndHostSet(win, this)
189
190
  });
190
191
  this.connect(userConfig);
191
192
  } catch (e) {
@@ -221,5 +222,43 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
221
222
  reload(): void {
222
223
  this.router?.reload();
223
224
  }
225
+
226
+ publishMessage(message: SwcAppMessage): void {
227
+ // 메시지를 모든 connected component instances로 분배
228
+ this._swc_connected_instance.forEach((instance: any) => {
229
+ this._invokeMessageSubscribers(instance, message);
230
+ });
231
+ }
232
+
233
+ _invokeMessageSubscribers(instance: any, message: SwcAppMessage) {
234
+ const messageSubscribers = getSubscribeSwcAppMessageWhileConnectedMetadata(instance);
235
+ if (messageSubscribers && Array.isArray(messageSubscribers)) {
236
+ messageSubscribers.forEach((metadata: any) => {
237
+ const methodName = metadata.propertyKey;
238
+ const messageType = metadata.messageType;
239
+ const filter = metadata.filter;
240
+
241
+ // 메시지 타입 확인
242
+ let typeMatched = false;
243
+ if (!messageType) {
244
+ // messageType이 없으면 모든 메시지 매칭 (와일드카드)
245
+ typeMatched = true;
246
+ } else if (message.type === messageType) {
247
+ typeMatched = true;
248
+ }
249
+
250
+ // 필터 적용
251
+ let filterMatched = true;
252
+ if (filter && typeMatched) {
253
+ filterMatched = filter(message);
254
+ }
255
+
256
+ // 조건을 만족하면 메서드 호출
257
+ if (typeMatched && filterMatched && typeof instance[methodName] === 'function') {
258
+ instance[methodName](message);
259
+ }
260
+ });
261
+ }
262
+ }
224
263
  };
225
264
  }