@dooboostore/simple-web-component 1.0.33 → 1.0.34

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 (114) hide show
  1. package/dist/cjs/decorators/addEventListener.js.map +1 -1
  2. package/dist/cjs/decorators/applyAttribute.js +67 -57
  3. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  4. package/dist/cjs/decorators/applyClass.js +80 -70
  5. package/dist/cjs/decorators/applyClass.js.map +2 -2
  6. package/dist/cjs/decorators/applyNode.js +1 -8
  7. package/dist/cjs/decorators/applyNode.js.map +2 -2
  8. package/dist/cjs/decorators/applyStyle.js +66 -56
  9. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  10. package/dist/cjs/decorators/attribute.js +35 -29
  11. package/dist/cjs/decorators/attribute.js.map +2 -2
  12. package/dist/cjs/decorators/changedAttributeHost.js +32 -12
  13. package/dist/cjs/decorators/changedAttributeHost.js.map +2 -2
  14. package/dist/cjs/decorators/elementDefine.js +29 -16
  15. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  16. package/dist/cjs/decorators/emitCustomEvent.js +57 -44
  17. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  18. package/dist/cjs/decorators/setProperty.js +50 -39
  19. package/dist/cjs/decorators/setProperty.js.map +2 -2
  20. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  21. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
  22. package/dist/cjs/elements/SwcAppEngine.js +7 -7
  23. package/dist/cjs/elements/SwcAppEngine.js.map +3 -3
  24. package/dist/cjs/elements/SwcAppMixin.js +60 -42
  25. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  26. package/dist/cjs/elements/SwcChoose.js +19 -15
  27. package/dist/cjs/elements/SwcChoose.js.map +2 -2
  28. package/dist/cjs/elements/register.js +21 -16
  29. package/dist/cjs/elements/register.js.map +2 -2
  30. package/dist/cjs/utils/Utils.js +7 -3
  31. package/dist/cjs/utils/Utils.js.map +2 -2
  32. package/dist/esm/decorators/addEventListener.js.map +1 -1
  33. package/dist/esm/decorators/applyAttribute.js +67 -57
  34. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  35. package/dist/esm/decorators/applyClass.js +80 -70
  36. package/dist/esm/decorators/applyClass.js.map +2 -2
  37. package/dist/esm/decorators/applyNode.js +1 -8
  38. package/dist/esm/decorators/applyNode.js.map +2 -2
  39. package/dist/esm/decorators/applyStyle.js +66 -56
  40. package/dist/esm/decorators/applyStyle.js.map +2 -2
  41. package/dist/esm/decorators/attribute.js +35 -29
  42. package/dist/esm/decorators/attribute.js.map +2 -2
  43. package/dist/esm/decorators/changedAttributeHost.js +32 -12
  44. package/dist/esm/decorators/changedAttributeHost.js.map +2 -2
  45. package/dist/esm/decorators/elementDefine.js +30 -17
  46. package/dist/esm/decorators/elementDefine.js.map +2 -2
  47. package/dist/esm/decorators/emitCustomEvent.js +57 -44
  48. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  49. package/dist/esm/decorators/setProperty.js +50 -39
  50. package/dist/esm/decorators/setProperty.js.map +2 -2
  51. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +1 -1
  52. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +1 -1
  53. package/dist/esm/elements/SwcAppEngine.js +6 -6
  54. package/dist/esm/elements/SwcAppEngine.js.map +2 -2
  55. package/dist/esm/elements/SwcAppMixin.js +60 -42
  56. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  57. package/dist/esm/elements/SwcChoose.js +20 -16
  58. package/dist/esm/elements/SwcChoose.js.map +2 -2
  59. package/dist/esm/elements/register.js +22 -17
  60. package/dist/esm/elements/register.js.map +2 -2
  61. package/dist/esm/utils/Utils.js +7 -3
  62. package/dist/esm/utils/Utils.js.map +2 -2
  63. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +425 -335
  64. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +3 -3
  65. package/dist/types/decorators/addEventListener.d.ts +4 -1
  66. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  67. package/dist/types/decorators/applyAttribute.d.ts +5 -1
  68. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  69. package/dist/types/decorators/applyClass.d.ts +4 -0
  70. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  71. package/dist/types/decorators/applyNode.d.ts +4 -1
  72. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  73. package/dist/types/decorators/applyStyle.d.ts +5 -1
  74. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  75. package/dist/types/decorators/attribute.d.ts +5 -0
  76. package/dist/types/decorators/attribute.d.ts.map +1 -1
  77. package/dist/types/decorators/changedAttributeHost.d.ts +13 -3
  78. package/dist/types/decorators/changedAttributeHost.d.ts.map +1 -1
  79. package/dist/types/decorators/elementDefine.d.ts +1 -1
  80. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  81. package/dist/types/decorators/emitCustomEvent.d.ts +5 -1
  82. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  83. package/dist/types/decorators/setProperty.d.ts +5 -1
  84. package/dist/types/decorators/setProperty.d.ts.map +1 -1
  85. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +2 -2
  86. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +1 -1
  87. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +2 -2
  88. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
  89. package/dist/types/elements/SwcAppEngine.d.ts +6 -3
  90. package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
  91. package/dist/types/elements/SwcAppMixin.d.ts +5 -3
  92. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  93. package/dist/types/elements/register.d.ts.map +1 -1
  94. package/dist/types/utils/Utils.d.ts.map +1 -1
  95. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +425 -335
  96. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +3 -3
  97. package/package.json +3 -3
  98. package/src/decorators/addEventListener.ts +1 -1
  99. package/src/decorators/applyAttribute.ts +74 -61
  100. package/src/decorators/applyClass.ts +91 -77
  101. package/src/decorators/applyNode.ts +3 -12
  102. package/src/decorators/applyStyle.ts +75 -61
  103. package/src/decorators/attribute.ts +55 -43
  104. package/src/decorators/changedAttributeHost.ts +47 -14
  105. package/src/decorators/elementDefine.ts +38 -20
  106. package/src/decorators/emitCustomEvent.ts +65 -49
  107. package/src/decorators/setProperty.ts +58 -44
  108. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +2 -2
  109. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +2 -2
  110. package/src/elements/SwcAppEngine.ts +11 -12
  111. package/src/elements/SwcAppMixin.ts +76 -44
  112. package/src/elements/SwcChoose.ts +28 -7
  113. package/src/elements/register.ts +28 -7
  114. package/src/utils/Utils.ts +15 -5
@@ -6,12 +6,12 @@ export const SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY = Symbo
6
6
  export interface SwcAppRouteChangeSubscriberMetadata {
7
7
  propertyKey: string | symbol;
8
8
  pathPattern?: string | string[];
9
- filter?: (router: Router) => boolean;
9
+ filter?: (router: Router, currentThis: any) => boolean;
10
10
  }
11
11
 
12
12
  export interface SwcAppRouteChangeOptions {
13
13
  path?: string | string[];
14
- filter?: (router: Router) => boolean;
14
+ filter?: (router: Router, currentThis: any) => boolean;
15
15
  }
16
16
 
17
17
  function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteChangeOptions): MethodDecorator {
@@ -1,26 +1,23 @@
1
1
  import { SimpleApplication } from '@dooboostore/simple-boot/SimpleApplication';
2
- import { PathRouter } from '@dooboostore/core-web';
3
- import { HashRouter } from '@dooboostore/core-web';
2
+ import { HashRouter, PathRouter, Router, RouterEventType } from '@dooboostore/core-web';
4
3
  import { ElementRouter } from '../router/ElementRouter';
5
4
  import { SimOption } from '@dooboostore/simple-boot/SimOption';
6
- import { Router, RouterEventType } from '@dooboostore/core-web';
7
- import { Subscription } from '@dooboostore/core';
8
- import { ConstructorType, OptionalType } from '@dooboostore/core';
9
- import { FunctionUtils } from '@dooboostore/core';
10
- import { SwcUtils } from '../utils/Utils';
5
+ import { ConstructorType, OptionalType, Subscription } from '@dooboostore/core';
11
6
 
12
7
  import { SwcAppInterface } from '../types';
13
- import {Intent} from "@dooboostore/simple-boot";
8
+ import { SimConfig } from '@dooboostore/simple-boot';
14
9
 
15
10
  export type SwcConfigType = {
16
11
  routeType: 'path' | 'hash' | 'element';
17
- connectMode?: 'direct' | 'swap';
12
+ connectMode?: 'direct' | 'swap' | 'clear-swap';
18
13
  container?: symbol;
14
+ otherInstanceSim?: Map<ConstructorType<any> | Function | SimConfig | symbol, any>;
19
15
  path?: string;
20
16
  window: Window;
21
17
  onEngineStarted?: (sp: SimpleApplication, app: SwcAppInterface) => void;
22
18
  onConnected?: (app: SwcAppInterface) => void;
23
19
  onDisconnected?: (app: SwcAppInterface) => void;
20
+ onRouteChanged?: (event: RouterEventType, app: SwcAppInterface) => void;
24
21
  };
25
22
 
26
23
  export type SwcAttributeConfigType = OptionalType<SwcConfigType, 'routeType' | 'window'>;
@@ -52,15 +49,17 @@ export class SwcAppEngine {
52
49
  // console.log('vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv', this.router)
53
50
 
54
51
  // App start
55
- const containerSymbol = this._config.container || (this.host as any).getContainerSymbol?.();
56
52
  this.simpleApplication = new SimpleApplication(
57
53
  new SimOption({
58
54
  excludeProxys: [Node],
59
- container: containerSymbol
55
+ container: this._config.container
60
56
  })
61
57
  );
62
58
 
63
59
  const otherInstanceSim = new Map<any, any>();
60
+ this.config.otherInstanceSim?.forEach((v, k) => {
61
+ otherInstanceSim.set(k, v);
62
+ });
64
63
  if (this.router) otherInstanceSim.set(Router, this.router);
65
64
  this.simpleApplication.run(otherInstanceSim);
66
65
 
@@ -68,7 +67,7 @@ export class SwcAppEngine {
68
67
  this._config.onEngineStarted(this.simpleApplication, this.host as unknown as SwcAppInterface);
69
68
  }
70
69
  } catch (e) {
71
- console.error('[SWC-APP-ENGINE] Init failed:', e);
70
+ console.error('[SWC-APP-ENGINE] Init failed:', e, this._config);
72
71
  }
73
72
  }
74
73
 
@@ -12,6 +12,8 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
12
12
  return class extends Base implements SwcAppInterface {
13
13
  __swc_engine = new SwcAppEngine(this as any);
14
14
  _swc_connected_instance = new Set<any>();
15
+ _swc_started_instances = new WeakSet<any>();
16
+ _swc_notified_routes = new WeakMap<any, RouterEventType>();
15
17
  _routerSubscription?: Subscription;
16
18
  _lastRouterEvent?: RouterEventType;
17
19
 
@@ -29,11 +31,15 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
29
31
  return this.__swc_engine.router;
30
32
  }
31
33
 
32
- _invokeRouteChangeSubscribers(instance: any, re: RouterEventType) {
34
+ async _invokeRouteChangeSubscribers(instance: any, re: RouterEventType) {
35
+ // 이미 이 라우트 이벤트에 대해 처리된 인스턴스라면 스킵 (동시성/중복 방지)
36
+ if (this._swc_notified_routes.get(instance) === re) return;
37
+ this._swc_notified_routes.set(instance, re);
38
+
33
39
  const routeChangeSubscribers = getSubscribeSwcAppRouteChangeWhileConnectedMetadata(instance);
34
40
  if (routeChangeSubscribers && Array.isArray(routeChangeSubscribers)) {
35
- routeChangeSubscribers.forEach((metadata: any) => {
36
- const methodName = metadata.propertyKey || metadata;
41
+ const ps = routeChangeSubscribers.map(async metadata => {
42
+ const methodName = metadata.propertyKey;
37
43
  const pathPattern = metadata.pathPattern;
38
44
  const filter = metadata.filter;
39
45
 
@@ -62,13 +68,14 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
62
68
  }
63
69
 
64
70
  // Filter validation
65
- const filterPassed = !filter || filter(this.router!);
71
+ const filterPassed = !filter || filter(this.router!, instance);
66
72
 
67
73
  // Invoke method if conditions pass
68
- if (pathMatched && filterPassed) {
69
- instance[methodName]?.({...re, pathData: pathData});
74
+ if (pathMatched && filterPassed && instance[methodName]) {
75
+ await instance[methodName]({ ...re, pathData: pathData });
70
76
  }
71
77
  });
78
+ return await Promise.allSettled(ps);
72
79
  }
73
80
  }
74
81
 
@@ -89,19 +96,20 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
89
96
  _disconnected(instance: any) {
90
97
  if (instance) {
91
98
  this._swc_connected_instance.delete(instance);
99
+ this._swc_started_instances.delete(instance);
100
+ this._swc_notified_routes.delete(instance);
92
101
  }
93
102
  }
94
103
 
95
- _handleRouteChange(route: RouterEventType) {
104
+ async _handleRouteChange(route: RouterEventType) {
105
+ // Save last router event
106
+ this._lastRouterEvent = route;
96
107
  if (route.triggerPoint === 'end') {
97
108
  // Iterate through all connected component instances
98
- this._swc_connected_instance.forEach((instance: any) => {
99
- this._invokeRouteChangeSubscribers(instance, route);
100
- });
109
+ const swcConnectedInstance = Array.from(this._swc_connected_instance);
110
+ const ps = swcConnectedInstance.map((instance: any) => this._invokeRouteChangeSubscribers(instance, route));
111
+ await Promise.allSettled(ps);
101
112
  }
102
-
103
- // Save last router event
104
- this._lastRouterEvent = route;
105
113
  }
106
114
 
107
115
  async connect(config?: SwcAttributeConfigType) {
@@ -113,29 +121,44 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
113
121
 
114
122
  const mode = config?.connectMode || 'direct';
115
123
 
124
+ // console.log('-------mode', mode);
116
125
  if (mode === 'direct') {
117
126
  await this.__swc_engine.connect(swcConfig);
118
127
  this.setAttribute('swc-connect-mode', 'direct');
119
- } else if (mode === 'swap' && !this.parentNode) {
120
- await this.__swc_engine.connect(swcConfig);
121
- this.setAttribute('swc-connect-mode', 'direct');
122
-
123
- const clonedApp = this.cloneNode(true) as any;
124
- clonedApp.style.display = 'none';
125
- this.parentNode.insertBefore(clonedApp, this.nextSibling);
126
-
127
- try {
128
- await clonedApp.connect({ ...(config || {}), connectMode: 'direct' });
129
- if (this.parentNode) {
130
- this.parentNode.removeChild(this);
131
- }
132
- clonedApp.setAttribute('swc-connect-mode', 'swap');
133
- clonedApp.style.display = '';
134
- } catch (e) {
135
- if (clonedApp.parentNode) {
136
- clonedApp.parentNode.removeChild(clonedApp);
128
+ } else if (mode === 'swap' || mode === 'clear-swap') {
129
+ if (!this.parentNode) {
130
+ // 부모가 없으면 swap을 할 수 없으므로 direct로 폴백합니다.
131
+ await this.__swc_engine.connect(swcConfig);
132
+ this.setAttribute('swc-connect-mode', 'direct');
133
+ } else {
134
+ // 1. 현재 SSR 상태(화면)를 그대로 유지한 채로, 백그라운드용 클론을 만듭니다.
135
+ const clonedApp = this.cloneNode(mode === 'swap') as any; // clear-swap 모드면 자식 노드를 클론하지 않음(false)
136
+ clonedApp.style.display = 'none';
137
+
138
+ // 2. DOM에 클론을 몰래 붙입니다.
139
+ this.parentNode.insertBefore(clonedApp, this.nextSibling);
140
+
141
+ try {
142
+ // 3. 클론을 direct 모드로 연결(초기화/렌더링) 시킵니다.
143
+ await clonedApp.connect({ ...(config || {}), connectMode: 'direct' });
144
+
145
+ // 4. 클론의 렌더링이 완전히 끝나면, 기존 SSR 화면(this)을 지우고 클론을 보여줍니다.
146
+ if (this.parentNode) {
147
+ this.parentNode.removeChild(this);
148
+ }
149
+ clonedApp.style.display = '';
150
+ clonedApp.setAttribute('swc-connect-mode', mode);
151
+
152
+ // ★ 매우 중요: 교체가 완료되었으므로 기존 앱(this)은 여기서 즉시 종료하여 불필요한 라우터/이벤트 구독을 막아야 합니다!
153
+ return;
154
+ } catch (e) {
155
+ // 실패 시 클론을 지우고 원본을 direct로 강제 연결합니다.
156
+ if (clonedApp.parentNode) {
157
+ clonedApp.parentNode.removeChild(clonedApp);
158
+ }
159
+ await this.__swc_engine.connect(swcConfig);
160
+ this.setAttribute('swc-connect-mode', 'direct');
137
161
  }
138
- throw e;
139
162
  }
140
163
  }
141
164
 
@@ -145,32 +168,41 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
145
168
  });
146
169
  // Invoke @onConnectedSwcApp lifecycle methods on all connected component instances
147
170
  // const hostSet = SwcUtils.getHostSet(this as any);
148
- this._swc_connected_instance.forEach((instance: any) => {
149
- this._invokeOnConnectedSwcAppStarted(instance);
150
- });
151
-
171
+ const scis = Array.from(this._swc_connected_instance);
172
+ await Promise.allSettled(scis.map(instance => this._invokeOnConnectedSwcAppStarted(instance)));
173
+ // this._swc_connected_instance.forEach((instance: any) => {
174
+ // this._invokeOnConnectedSwcAppStarted(instance);
175
+ // });
152
176
 
153
177
  // Subscribe to router changes after connect
154
178
  if (!this._routerSubscription && this.router) {
179
+ const config = this.__swc_engine.config;
155
180
  this._routerSubscription = this.router.observable.subscribe((route: RouterEventType) => {
156
181
  //@ts-ignore
157
182
  // console.log('Route changed:', route, this._swcId);
158
- this._handleRouteChange(route);
183
+ this._handleRouteChange(route).then(it => {
184
+ config?.onRouteChanged?.(route, this);
185
+ });
159
186
  });
160
187
  // Navigate to initial path if specified
161
- const config = this.__swc_engine.config;
162
188
  // if (config?.path) {
163
189
  // this.router.go(config.path);
164
190
  // }
165
191
  }
166
192
  }
167
193
 
168
- _invokeOnConnectedSwcAppStarted(instance: any) {
194
+ async _invokeOnConnectedSwcAppStarted(instance: any) {
195
+ // 이미 시작된 인스턴스라면 스킵 (비동기 병렬 중복 호출 방지)
196
+ if (this._swc_started_instances.has(instance)) return;
197
+ this._swc_started_instances.add(instance);
198
+
169
199
  const startedMethods = findAllLifecycleMetadata(instance, ON_CONNECTED_SWC_APP_METADATA_KEY);
170
200
  if (startedMethods) {
171
- for (const m of startedMethods) {
172
- instance._invokeLifecycleMethod(m);
173
- }
201
+ const ps = startedMethods.map(m => instance._invokeLifecycleMethod(m));
202
+ return await Promise.allSettled(ps)
203
+ // for (const m of startedMethods) {
204
+ // instance._invokeLifecycleMethod(m);
205
+ // }
174
206
  }
175
207
  }
176
208
 
@@ -233,7 +265,7 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
233
265
  _invokeMessageSubscribers(instance: any, message: SwcAppMessage) {
234
266
  const messageSubscribers = getSubscribeSwcAppMessageWhileConnectedMetadata(instance);
235
267
  if (messageSubscribers && Array.isArray(messageSubscribers)) {
236
- messageSubscribers.forEach((metadata: any) => {
268
+ messageSubscribers.forEach(metadata => {
237
269
  const methodName = metadata.propertyKey;
238
270
  const messageType = metadata.messageType;
239
271
  const filter = metadata.filter;
@@ -250,7 +282,7 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
250
282
  // 필터 적용
251
283
  let filterMatched = true;
252
284
  if (filter && typeMatched) {
253
- filterMatched = filter(message);
285
+ filterMatched = filter(message, instance);
254
286
  }
255
287
 
256
288
  // 조건을 만족하면 메서드 호출
@@ -3,10 +3,12 @@ import { SwcUtils } from '../utils/Utils';
3
3
  import { FunctionUtils, ActionExpression } from '@dooboostore/core';
4
4
  import { ConvertUtils } from '@dooboostore/core-web';
5
5
  import { SwcChooseInterface } from '../types';
6
- import { attributeHost } from '../decorators';
6
+ import { attributeHost, getAttributeValue, getElementConfig } from '../decorators';
7
7
 
8
8
  class SwcChoose extends HTMLTemplateElement implements SwcChooseInterface {
9
- @attributeHost('value')
9
+ // @attributeHost('value')
10
+ // fetchValue: any;
11
+
10
12
  _value: any;
11
13
 
12
14
  @attributeHost('replace-wrap')
@@ -20,12 +22,29 @@ class SwcChoose extends HTMLTemplateElement implements SwcChooseInterface {
20
22
  }
21
23
 
22
24
  set value(nv: any) {
23
- this.refresh(nv);
25
+ this._value = nv;
26
+ this.refresh(this._value);
27
+ }
28
+
29
+ constructor() {
30
+ super();
31
+ // console.log('swc chooooooooooooooooooooooooose constructor called!');
32
+ // console.log('swc cccccccss', this.getAttribute('value'));
33
+ }
34
+
35
+ // static get observedAttributes() {
36
+ // return ['value'];
37
+ // }
38
+
39
+ attributeChangedCallback(na, o, n) {
40
+ // console.log('-----------------choooooooose attr origin', na, o, n);
24
41
  }
25
42
 
26
43
  @changedAttributeHost('value')
27
- private setValue() {
28
- this.refresh();
44
+ private setValue(value: any, o: string, n: string) {
45
+ // console.log('-----------------choooooooose attr setValue', value, o, n);
46
+ this._value = value;
47
+ this.refresh(this._value);
29
48
  }
30
49
 
31
50
  @changedAttributeHost('replace-wrap')
@@ -55,11 +74,13 @@ class SwcChoose extends HTMLTemplateElement implements SwcChooseInterface {
55
74
  return ae.getUnprocessedTemplate();
56
75
  }
57
76
 
58
- refresh(value = this._value) {
77
+ refresh(value?: any) {
78
+ value = getAttributeValue(this, 'value') ?? this._value;
79
+ // console.log('chooooooooo refresh->', value);
59
80
  const portal = this.parentElement;
60
81
  if (!portal) return;
61
82
 
62
- const win = this.ownerDocument?.defaultView || window;
83
+ const win = (getElementConfig(this).window ?? this.ownerDocument?.defaultView) || window;
63
84
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
64
85
  const groupArgs = { ...helperSet, $value: value };
65
86
 
@@ -1,4 +1,4 @@
1
- import { elementDefine, attributeHost, changedAttributeHost } from '../decorators';
1
+ import { getElementConfig, elementDefine, attributeHost, changedAttributeHost, getAttributeValue } from '../decorators';
2
2
  import { SwcAppMixin } from './SwcAppMixin';
3
3
  import { SwcUtils } from '../utils/Utils';
4
4
  import { FunctionUtils,ActionExpression } from '@dooboostore/core';
@@ -318,7 +318,9 @@ export const registerAllElements = (w: any): Record<string, Constructor<HTMLElem
318
318
 
319
319
  @elementDefine('swc-choose', { extends: 'template', window: w })
320
320
  class SwcChoose extends HTMLTemplateElement {
321
- @attributeHost('value')
321
+ // @attributeHost('value')
322
+ // fetchValue: any;
323
+
322
324
  _value: any;
323
325
 
324
326
  @attributeHost('replace-wrap')
@@ -332,12 +334,29 @@ export const registerAllElements = (w: any): Record<string, Constructor<HTMLElem
332
334
  }
333
335
 
334
336
  set value(nv: any) {
335
- this.refresh(nv);
337
+ this._value = nv;
338
+ this.refresh(this._value);
339
+ }
340
+
341
+ constructor() {
342
+ super();
343
+ // console.log('swc chooooooooooooooooooooooooose constructor called!');
344
+ // console.log('swc cccccccss', this.getAttribute('value'));
345
+ }
346
+
347
+ // static get observedAttributes() {
348
+ // return ['value'];
349
+ // }
350
+
351
+ attributeChangedCallback(na, o, n) {
352
+ // console.log('-----------------choooooooose attr origin', na, o, n);
336
353
  }
337
354
 
338
355
  @changedAttributeHost('value')
339
- private setValue() {
340
- this.refresh();
356
+ private setValue(value: any, o: string, n: string) {
357
+ // console.log('-----------------choooooooose attr setValue', value, o, n);
358
+ this._value = value;
359
+ this.refresh(this._value);
341
360
  }
342
361
 
343
362
  @changedAttributeHost('replace-wrap')
@@ -367,11 +386,13 @@ export const registerAllElements = (w: any): Record<string, Constructor<HTMLElem
367
386
  return ae.getUnprocessedTemplate();
368
387
  }
369
388
 
370
- refresh(value = this._value) {
389
+ refresh(value?: any) {
390
+ value = getAttributeValue(this, 'value') ?? this._value;
391
+ // console.log('chooooooooo refresh->', value);
371
392
  const portal = this.parentElement;
372
393
  if (!portal) return;
373
394
 
374
- const win = this.ownerDocument?.defaultView || window;
395
+ const win = (getElementConfig(this).window ?? this.ownerDocument?.defaultView) || window;
375
396
  const helperSet = SwcUtils.getHelperAndHostSet(win, this);
376
397
  const groupArgs = { ...helperSet, $value: value };
377
398
 
@@ -249,8 +249,10 @@ export namespace SwcUtils {
249
249
  };
250
250
 
251
251
  export const getAppHosts = (el: HTMLElement): SwcAppInterface[] => {
252
- const hosts = getHosts(el);
253
- return hosts.filter(host => host.tagName.toLowerCase() === 'swc-app' || host.getAttribute('is')?.startsWith('swc-app-')) as SwcAppInterface[];
252
+ // const hosts = getHosts(el);
253
+ // return hosts.filter(host => host.tagName.toLowerCase() === 'swc-app' || host.getAttribute('is')?.startsWith('swc-app-')) as SwcAppInterface[];
254
+ const hosts = SwcUtils.findAllParentAppHostsDirect(el);
255
+ return hosts;
254
256
  };
255
257
 
256
258
  export const getAppHost = (el: HTMLElement): SwcAppInterface | undefined => {
@@ -277,7 +279,15 @@ export namespace SwcUtils {
277
279
  */
278
280
  export const findAllParentAppHostsDirect = (el: HTMLElement): SwcAppInterface[] => {
279
281
  const appHosts: SwcAppInterface[] = [];
280
-
282
+
283
+ const w = el.ownerDocument?.defaultView || ((typeof window !== 'undefined' ? window : undefined) as any);
284
+
285
+ // Guard against SSR environment where window might be undefined
286
+ if (!w) {
287
+ return appHosts;
288
+ }
289
+
290
+ // console.log('------?',w.ShadowRoot);
281
291
  // el 자체부터 시작 (el이 app host일 수도 있음)
282
292
  let current: HTMLElement | null = el;
283
293
 
@@ -296,9 +306,9 @@ export namespace SwcUtils {
296
306
  } else {
297
307
  // parentElement가 없음 = Shadow root의 직접 자식일 수 있음
298
308
  const root = current.getRootNode();
299
- if (root instanceof ShadowRoot) {
309
+ if (w.ShadowRoot && root instanceof w.ShadowRoot) {
300
310
  // Shadow host로 올라가기
301
- current = root.host as HTMLElement;
311
+ current = (root as ShadowRoot).host as HTMLElement;
302
312
  } else {
303
313
  // Document root 도달
304
314
  break;