@dooboostore/simple-web-component 1.0.34 → 1.0.36
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 +44 -51
- package/dist/cjs/decorators/addEventListener.js +12 -4
- package/dist/cjs/decorators/addEventListener.js.map +2 -2
- package/dist/cjs/decorators/applyAttribute.js +19 -18
- package/dist/cjs/decorators/applyAttribute.js.map +2 -2
- package/dist/cjs/decorators/applyClass.js +23 -22
- package/dist/cjs/decorators/applyClass.js.map +2 -2
- package/dist/cjs/decorators/applyNode.js +22 -17
- package/dist/cjs/decorators/applyNode.js.map +2 -2
- package/dist/cjs/decorators/applyStyle.js +20 -19
- package/dist/cjs/decorators/applyStyle.js.map +2 -2
- package/dist/cjs/decorators/attribute.js +17 -16
- package/dist/cjs/decorators/attribute.js.map +2 -2
- package/dist/cjs/decorators/{changedAttributeHost.js → changedAttributeThis.js} +6 -6
- package/dist/cjs/decorators/changedAttributeThis.js.map +7 -0
- package/dist/cjs/decorators/elementDefine.js +234 -188
- package/dist/cjs/decorators/elementDefine.js.map +2 -2
- package/dist/cjs/decorators/emitCustomEvent.js +24 -16
- package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
- package/dist/cjs/decorators/index.js +1 -1
- package/dist/cjs/decorators/index.js.map +1 -1
- package/dist/cjs/decorators/lifecycles.js +15 -17
- package/dist/cjs/decorators/lifecycles.js.map +2 -2
- package/dist/cjs/decorators/query.js +38 -60
- package/dist/cjs/decorators/query.js.map +2 -2
- package/dist/cjs/decorators/queryAll.js +31 -63
- package/dist/cjs/decorators/queryAll.js.map +2 -2
- package/dist/cjs/decorators/setProperty.js +13 -12
- package/dist/cjs/decorators/setProperty.js.map +2 -2
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -2
- package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/cjs/elements/SwcAppEngine.js +8 -2
- package/dist/cjs/elements/SwcAppEngine.js.map +2 -2
- package/dist/cjs/elements/SwcAppMixin.js +120 -65
- package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
- package/dist/cjs/elements/SwcAsync.js +31 -21
- package/dist/cjs/elements/SwcAsync.js.map +2 -2
- package/dist/cjs/elements/SwcChoose.js +53 -34
- package/dist/cjs/elements/SwcChoose.js.map +2 -2
- package/dist/cjs/elements/SwcIf.js +54 -32
- package/dist/cjs/elements/SwcIf.js.map +2 -2
- package/dist/cjs/elements/SwcLoop.js +111 -37
- package/dist/cjs/elements/SwcLoop.js.map +2 -2
- package/dist/cjs/elements/register.js +249 -122
- package/dist/cjs/elements/register.js.map +2 -2
- package/dist/cjs/router/ElementRouter.js +4 -2
- package/dist/cjs/router/ElementRouter.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/utils/Utils.js +31 -17
- package/dist/cjs/utils/Utils.js.map +2 -2
- package/dist/esm/decorators/addEventListener.js +12 -4
- package/dist/esm/decorators/addEventListener.js.map +2 -2
- package/dist/esm/decorators/applyAttribute.js +19 -18
- package/dist/esm/decorators/applyAttribute.js.map +2 -2
- package/dist/esm/decorators/applyClass.js +23 -22
- package/dist/esm/decorators/applyClass.js.map +2 -2
- package/dist/esm/decorators/applyNode.js +22 -17
- package/dist/esm/decorators/applyNode.js.map +2 -2
- package/dist/esm/decorators/applyStyle.js +20 -19
- package/dist/esm/decorators/applyStyle.js.map +2 -2
- package/dist/esm/decorators/attribute.js +17 -16
- package/dist/esm/decorators/attribute.js.map +2 -2
- package/dist/esm/decorators/{changedAttributeHost.js → changedAttributeThis.js} +3 -3
- package/dist/esm/decorators/changedAttributeThis.js.map +7 -0
- package/dist/esm/decorators/elementDefine.js +233 -187
- package/dist/esm/decorators/elementDefine.js.map +2 -2
- package/dist/esm/decorators/emitCustomEvent.js +24 -16
- package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
- package/dist/esm/decorators/index.js +1 -1
- package/dist/esm/decorators/index.js.map +1 -1
- package/dist/esm/decorators/lifecycles.js +15 -17
- package/dist/esm/decorators/lifecycles.js.map +2 -2
- package/dist/esm/decorators/query.js +38 -60
- package/dist/esm/decorators/query.js.map +2 -2
- package/dist/esm/decorators/queryAll.js +31 -63
- package/dist/esm/decorators/queryAll.js.map +2 -2
- package/dist/esm/decorators/setProperty.js +13 -12
- package/dist/esm/decorators/setProperty.js.map +2 -2
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js +2 -2
- package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +2 -2
- package/dist/esm/elements/SwcAppEngine.js +9 -2
- package/dist/esm/elements/SwcAppEngine.js.map +2 -2
- package/dist/esm/elements/SwcAppMixin.js +122 -66
- package/dist/esm/elements/SwcAppMixin.js.map +2 -2
- package/dist/esm/elements/SwcAsync.js +32 -22
- package/dist/esm/elements/SwcAsync.js.map +2 -2
- package/dist/esm/elements/SwcChoose.js +54 -35
- package/dist/esm/elements/SwcChoose.js.map +2 -2
- package/dist/esm/elements/SwcIf.js +55 -33
- package/dist/esm/elements/SwcIf.js.map +2 -2
- package/dist/esm/elements/SwcLoop.js +112 -38
- package/dist/esm/elements/SwcLoop.js.map +2 -2
- package/dist/esm/elements/register.js +250 -123
- package/dist/esm/elements/register.js.map +2 -2
- package/dist/esm/router/ElementRouter.js +5 -2
- package/dist/esm/router/ElementRouter.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/Utils.js +31 -17
- package/dist/esm/utils/Utils.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +563 -557
- package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
- package/dist/types/decorators/addEventListener.d.ts +5 -7
- package/dist/types/decorators/addEventListener.d.ts.map +1 -1
- package/dist/types/decorators/applyAttribute.d.ts +4 -4
- package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
- package/dist/types/decorators/applyClass.d.ts +6 -6
- package/dist/types/decorators/applyClass.d.ts.map +1 -1
- package/dist/types/decorators/applyNode.d.ts +7 -6
- package/dist/types/decorators/applyNode.d.ts.map +1 -1
- package/dist/types/decorators/applyStyle.d.ts +4 -4
- package/dist/types/decorators/applyStyle.d.ts.map +1 -1
- package/dist/types/decorators/attribute.d.ts +5 -5
- package/dist/types/decorators/attribute.d.ts.map +1 -1
- package/dist/types/decorators/changedAttributeThis.d.ts +18 -0
- package/dist/types/decorators/changedAttributeThis.d.ts.map +1 -0
- package/dist/types/decorators/elementDefine.d.ts.map +1 -1
- package/dist/types/decorators/emitCustomEvent.d.ts +11 -12
- package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
- package/dist/types/decorators/index.d.ts +1 -1
- package/dist/types/decorators/lifecycles.d.ts +10 -7
- package/dist/types/decorators/lifecycles.d.ts.map +1 -1
- package/dist/types/decorators/query.d.ts +17 -63
- package/dist/types/decorators/query.d.ts.map +1 -1
- package/dist/types/decorators/queryAll.d.ts +6 -63
- package/dist/types/decorators/queryAll.d.ts.map +1 -1
- package/dist/types/decorators/setProperty.d.ts +1 -1
- package/dist/types/decorators/setProperty.d.ts.map +1 -1
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +4 -5
- package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +1 -1
- package/dist/types/elements/SwcAppEngine.d.ts +4 -1
- package/dist/types/elements/SwcAppEngine.d.ts.map +1 -1
- package/dist/types/elements/SwcAppMixin.d.ts +11 -8
- package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
- package/dist/types/elements/register.d.ts.map +1 -1
- package/dist/types/types.d.ts +3 -2
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/Utils.d.ts +11 -8
- package/dist/types/utils/Utils.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +563 -557
- package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
- package/package.json +3 -3
- package/src/decorators/addEventListener.ts +11 -9
- package/src/decorators/applyAttribute.ts +16 -15
- package/src/decorators/applyClass.ts +18 -17
- package/src/decorators/applyNode.ts +34 -21
- package/src/decorators/applyStyle.ts +17 -16
- package/src/decorators/attribute.ts +21 -20
- package/src/decorators/{changedAttributeHost.ts → changedAttributeThis.ts} +13 -14
- package/src/decorators/elementDefine.ts +402 -358
- package/src/decorators/emitCustomEvent.ts +40 -31
- package/src/decorators/index.ts +1 -1
- package/src/decorators/lifecycles.ts +11 -10
- package/src/decorators/query.ts +51 -124
- package/src/decorators/queryAll.ts +30 -127
- package/src/decorators/setProperty.ts +12 -11
- package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +10 -10
- package/src/elements/SwcAppEngine.ts +10 -3
- package/src/elements/SwcAppMixin.ts +177 -97
- package/src/elements/SwcAsync.ts +32 -21
- package/src/elements/SwcChoose.ts +74 -37
- package/src/elements/SwcIf.ts +60 -23
- package/src/elements/SwcLoop.ts +141 -28
- package/src/elements/register.ts +300 -102
- package/src/types.ts +6 -5
- package/src/utils/Utils.ts +40 -23
- package/tsconfig.json +2 -2
- package/dist/cjs/decorators/changedAttributeHost.js.map +0 -7
- package/dist/esm/decorators/changedAttributeHost.js.map +0 -7
- package/dist/types/decorators/changedAttributeHost.d.ts +0 -19
- package/dist/types/decorators/changedAttributeHost.d.ts.map +0 -1
|
@@ -56,15 +56,16 @@ export const setProperty = (selector: string, propertyNameOrOptions?: string | P
|
|
|
56
56
|
targetEls.push(t);
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
if (selector === '
|
|
60
|
-
else if (selector === '
|
|
61
|
-
else if (selector === '
|
|
62
|
-
else if (selector === '
|
|
63
|
-
else if (selector === '
|
|
64
|
-
else if (selector === '
|
|
65
|
-
else if (selector === '
|
|
66
|
-
else if (selector === '
|
|
67
|
-
else if (selector === '
|
|
59
|
+
if (selector === '$this' || !selector) applyRoot(host);
|
|
60
|
+
else if (selector === '$host') applyRoot(hostSet.$host);
|
|
61
|
+
else if (selector === '$parentHost') applyRoot(hostSet.$parentHost);
|
|
62
|
+
else if (selector === '$appHost') applyRoot(hostSet.$appHost);
|
|
63
|
+
else if (selector === '$firstHost') applyRoot(hostSet.$firstHost);
|
|
64
|
+
else if (selector === '$lastHost') applyRoot(hostSet.$lastHost);
|
|
65
|
+
else if (selector === '$firstAppHost') applyRoot(hostSet.$firstAppHost);
|
|
66
|
+
else if (selector === '$lastAppHost') applyRoot(hostSet.$lastAppHost);
|
|
67
|
+
else if (selector === '$hosts') hostSet.$hosts.forEach(applyRoot);
|
|
68
|
+
else if (selector === '$appHosts') hostSet.$appHosts.forEach(applyRoot);
|
|
68
69
|
else {
|
|
69
70
|
const targetRoot = r === 'auto' ? (host.shadowRoot || host) : (r === 'shadow' ? host.shadowRoot : host);
|
|
70
71
|
if (targetRoot) {
|
|
@@ -106,6 +107,6 @@ export const setProperty = (selector: string, propertyNameOrOptions?: string | P
|
|
|
106
107
|
};
|
|
107
108
|
};
|
|
108
109
|
|
|
109
|
-
export const
|
|
110
|
-
return setProperty('
|
|
110
|
+
export const setPropertyThis = (propertyNameOrOptions?: string | PropertySetOptions, options: PropertySetOptions = {}): MethodDecorator => {
|
|
111
|
+
return setProperty('$this', propertyNameOrOptions, options);
|
|
111
112
|
};
|
|
@@ -3,14 +3,15 @@ import { Router } from '@dooboostore/core-web';
|
|
|
3
3
|
|
|
4
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
|
+
export type RoutePathType = string | string[] | ((currentThis: any) => string | string[]);
|
|
7
|
+
|
|
6
8
|
export interface SwcAppRouteChangeSubscriberMetadata {
|
|
7
9
|
propertyKey: string | symbol;
|
|
8
|
-
|
|
9
|
-
filter?: (router: Router, currentThis: any) => boolean;
|
|
10
|
+
options?: SwcAppRouteChangeOptions;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface SwcAppRouteChangeOptions {
|
|
13
|
-
path?:
|
|
14
|
+
path?: RoutePathType;
|
|
14
15
|
filter?: (router: Router, currentThis: any) => boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -25,8 +26,8 @@ function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteCha
|
|
|
25
26
|
list = [];
|
|
26
27
|
ReflectUtils.defineMetadata(SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY, list, constructor);
|
|
27
28
|
}
|
|
28
|
-
list.push({ propertyKey,
|
|
29
|
-
|
|
29
|
+
list.push({ propertyKey, options });
|
|
30
|
+
|
|
30
31
|
return descriptor;
|
|
31
32
|
};
|
|
32
33
|
}
|
|
@@ -35,8 +36,7 @@ function createSubscribeSwcAppRouteChangeWhileConnected(options?: SwcAppRouteCha
|
|
|
35
36
|
export function subscribeSwcAppRouteChangeWhileConnected(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
|
|
36
37
|
// 오버로드 시그니처 - 함수 호출 (괄호 있음)
|
|
37
38
|
export function subscribeSwcAppRouteChangeWhileConnected(): MethodDecorator;
|
|
38
|
-
export function subscribeSwcAppRouteChangeWhileConnected(pathPattern:
|
|
39
|
-
export function subscribeSwcAppRouteChangeWhileConnected(pathPatterns: string[]): MethodDecorator;
|
|
39
|
+
export function subscribeSwcAppRouteChangeWhileConnected(pathPattern: RoutePathType): MethodDecorator;
|
|
40
40
|
export function subscribeSwcAppRouteChangeWhileConnected(options: SwcAppRouteChangeOptions): MethodDecorator;
|
|
41
41
|
|
|
42
42
|
// 실제 구현 (이중 모드)
|
|
@@ -46,15 +46,15 @@ export function subscribeSwcAppRouteChangeWhileConnected(targetOrOptions?: any,
|
|
|
46
46
|
if (propertyKey && (typeof propertyKey === 'string' || typeof propertyKey === 'symbol')) {
|
|
47
47
|
return createSubscribeSwcAppRouteChangeWhileConnected({})(targetOrOptions, propertyKey, descriptor);
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
// 함수로 호출된 경우 (괄호 있음): @subscribeSwcAppRouteChangeWhileConnected() / @subscribeSwcAppRouteChangeWhileConnected('/path')
|
|
51
51
|
let options: SwcAppRouteChangeOptions = {};
|
|
52
52
|
|
|
53
53
|
if (Array.isArray(targetOrOptions)) {
|
|
54
54
|
// 배열: @subscribeSwcAppRouteChangeWhileConnected(['/path1', '/path2'])
|
|
55
55
|
options.path = targetOrOptions;
|
|
56
|
-
} else if (typeof targetOrOptions === 'string') {
|
|
57
|
-
//
|
|
56
|
+
} else if (typeof targetOrOptions === 'string' || typeof targetOrOptions === 'function') {
|
|
57
|
+
// 문자열 또는 함수: @subscribeSwcAppRouteChangeWhileConnected('/path')
|
|
58
58
|
options.path = targetOrOptions;
|
|
59
59
|
} else if (targetOrOptions && typeof targetOrOptions === 'object') {
|
|
60
60
|
// 객체: @subscribeSwcAppRouteChangeWhileConnected({ path: '/path', filter: ... })
|
|
@@ -17,7 +17,13 @@ export type SwcConfigType = {
|
|
|
17
17
|
onEngineStarted?: (sp: SimpleApplication, app: SwcAppInterface) => void;
|
|
18
18
|
onConnected?: (app: SwcAppInterface) => void;
|
|
19
19
|
onDisconnected?: (app: SwcAppInterface) => void;
|
|
20
|
-
|
|
20
|
+
|
|
21
|
+
onChildrenConnectedDone?: (app: SwcAppInterface) => void;
|
|
22
|
+
// onChildrenSwcAppStartedDone?: (app: SwcAppInterface) => void;
|
|
23
|
+
// childrenSwcAppStartedDoneCheckIntervalTime?: number;
|
|
24
|
+
onChildrenRouteChanged?: (event: RouterEventType, app: SwcAppInterface) => void;
|
|
25
|
+
childrenRouteChangedCheckIntervalTime?: number; // 자식 연결 완료 이벤트 디바운스 타임 (ms)
|
|
26
|
+
childrenConnectedDoneCheckIntervalTime?: number;
|
|
21
27
|
};
|
|
22
28
|
|
|
23
29
|
export type SwcAttributeConfigType = OptionalType<SwcConfigType, 'routeType' | 'window'>;
|
|
@@ -33,6 +39,7 @@ export class SwcAppEngine {
|
|
|
33
39
|
get config() {
|
|
34
40
|
return this._config;
|
|
35
41
|
}
|
|
42
|
+
|
|
36
43
|
async connect(config: SwcConfigType) {
|
|
37
44
|
try {
|
|
38
45
|
this._config = config;
|
|
@@ -51,13 +58,13 @@ export class SwcAppEngine {
|
|
|
51
58
|
// App start
|
|
52
59
|
this.simpleApplication = new SimpleApplication(
|
|
53
60
|
new SimOption({
|
|
54
|
-
excludeProxys: [Node],
|
|
61
|
+
excludeProxys: [(this._config.window as any).Node],
|
|
55
62
|
container: this._config.container
|
|
56
63
|
})
|
|
57
64
|
);
|
|
58
65
|
|
|
59
66
|
const otherInstanceSim = new Map<any, any>();
|
|
60
|
-
this.config
|
|
67
|
+
this.config?.otherInstanceSim?.forEach((v, k) => {
|
|
61
68
|
otherInstanceSim.set(k, v);
|
|
62
69
|
});
|
|
63
70
|
if (this.router) otherInstanceSim.set(Router, this.router);
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { FunctionUtils, Subscription
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Base: T) {
|
|
1
|
+
import {SwcAppEngine, SwcAttributeConfigType, SwcConfigType} from './SwcAppEngine';
|
|
2
|
+
import {SwcAppInterface, SwcAppMessage} from '../types';
|
|
3
|
+
import {SwcUtils} from '../utils/Utils';
|
|
4
|
+
import {debounceTimeIntervalLock, FunctionUtils, Subscription} from '@dooboostore/core';
|
|
5
|
+
import {RouterEventType} from '@dooboostore/core-web';
|
|
6
|
+
import {getSubscribeSwcAppRouteChangeWhileConnectedMetadata} from '../decorators/subscribeSwcAppRouteChangeWhileConnected';
|
|
7
|
+
import {getSubscribeSwcAppMessageWhileConnectedMetadata} from '../decorators/subscribeSwcAppMessageWhileConnected';
|
|
8
|
+
|
|
9
|
+
export function SwcAppMixin<T extends { new(...args: any[]): HTMLElement }>(Base: T) {
|
|
11
10
|
//@ts-ignore
|
|
12
11
|
return class extends Base implements SwcAppInterface {
|
|
13
12
|
__swc_engine = new SwcAppEngine(this as any);
|
|
14
13
|
_swc_connected_instance = new Set<any>();
|
|
15
|
-
|
|
16
|
-
_swc_notified_routes = new WeakMap<any, RouterEventType>();
|
|
14
|
+
// _swc_notified_routes = new WeakMap<any, RouterEventType>();
|
|
17
15
|
_routerSubscription?: Subscription;
|
|
18
16
|
_lastRouterEvent?: RouterEventType;
|
|
17
|
+
_routeChangeInvocations = 0;
|
|
18
|
+
_connectedInvocations = 0;
|
|
19
|
+
|
|
20
|
+
_childrenRouteChangedInterval: any;
|
|
21
|
+
_childrenConnectedDoneInterval: any;
|
|
19
22
|
|
|
20
23
|
/*
|
|
21
24
|
사파리 is 일경우
|
|
@@ -24,104 +27,171 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
|
|
|
24
27
|
저 polyfill에서는 자식부터 만들어지고 부모가 만들어진다 is일때 아 .. 이문제때문에 자식이 _connected_safari 에 강제로 자기자식넣어준다
|
|
25
28
|
*/
|
|
26
29
|
_connected_safari = [];
|
|
30
|
+
|
|
27
31
|
get simpleApplication() {
|
|
28
32
|
return this.__swc_engine.simpleApplication;
|
|
29
33
|
}
|
|
34
|
+
|
|
35
|
+
get config() {
|
|
36
|
+
return this.__swc_engine?.config;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
get router() {
|
|
31
|
-
return this.__swc_engine
|
|
40
|
+
return this.__swc_engine?.router;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
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);
|
|
44
|
+
if (instance.isConnected === false) return;
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
this._routeChangeInvocations++;
|
|
47
|
+
|
|
48
|
+
if (this._childrenRouteChangedInterval) {
|
|
49
|
+
clearInterval(this._childrenRouteChangedInterval);
|
|
50
|
+
}
|
|
51
|
+
this._childrenRouteChangedInterval = debounceTimeIntervalLock(
|
|
52
|
+
() => this._routeChangeInvocations === 0,
|
|
53
|
+
() => {
|
|
54
|
+
this._childrenRouteChangedInterval = null;
|
|
55
|
+
this.config.onChildrenRouteChanged(re, this)
|
|
56
|
+
},
|
|
57
|
+
this.config?.childrenConnectedDoneCheckIntervalTime ?? 30,
|
|
58
|
+
{setInterval: window.setInterval, clearInterval: window.clearInterval}
|
|
59
|
+
// {setInterval: window.setInterval, clearInterval: window.clearInterval}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// debounceTimeIntervalLock({
|
|
64
|
+
// unlockChecker: () => this._routeChangeInvocations === 0,
|
|
65
|
+
// unlocked: () => this.config.onChildrenRouteChanged(re, this)
|
|
66
|
+
// }, {
|
|
67
|
+
// intervalId: this._childrenRouteChangedInterval,
|
|
68
|
+
// setIntervalId: (id) => this._childrenRouteChangedInterval = id,
|
|
69
|
+
// intervalTime: this.config?.childrenRouteChangedCheckIntervalTime ?? 30
|
|
70
|
+
// }, {
|
|
71
|
+
// setInterval: window.setInterval,
|
|
72
|
+
// clearInterval: window.clearInterval
|
|
73
|
+
// });
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
// if (this._swc_notified_routes.get(instance) === re) {
|
|
77
|
+
// return;
|
|
78
|
+
// }
|
|
79
|
+
// this._swc_notified_routes.set(instance, re);
|
|
45
80
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
81
|
+
const routeChangeSubscribers = getSubscribeSwcAppRouteChangeWhileConnectedMetadata(instance);
|
|
82
|
+
if (routeChangeSubscribers && Array.isArray(routeChangeSubscribers)) {
|
|
83
|
+
const ps = routeChangeSubscribers.map(async metadata => {
|
|
84
|
+
const methodName = metadata.propertyKey;
|
|
85
|
+
let pathPattern = metadata.options?.path as any;
|
|
86
|
+
const filter = metadata.options?.filter;
|
|
87
|
+
|
|
88
|
+
if (typeof pathPattern === 'function') {
|
|
89
|
+
pathPattern = (pathPattern as Function)(instance);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let pathMatched = false;
|
|
93
|
+
let pathData: any = null;
|
|
94
|
+
|
|
95
|
+
if (!pathPattern) {
|
|
96
|
+
pathMatched = true;
|
|
97
|
+
pathData = {};
|
|
98
|
+
} else if (Array.isArray(pathPattern)) {
|
|
99
|
+
for (const pattern of pathPattern) {
|
|
100
|
+
const data = SwcUtils.parsePathPattern(pattern, re.path || '/');
|
|
101
|
+
if (data !== null) {
|
|
102
|
+
pathMatched = true;
|
|
103
|
+
pathData = data;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
62
106
|
}
|
|
107
|
+
} else {
|
|
108
|
+
pathData = SwcUtils.parsePathPattern(pathPattern, re.path || '/');
|
|
109
|
+
pathMatched = pathData !== null;
|
|
63
110
|
}
|
|
64
|
-
} else {
|
|
65
|
-
// 문자열
|
|
66
|
-
pathData = SwcUtils.parsePathPattern(pathPattern, re.path || '/');
|
|
67
|
-
pathMatched = pathData !== null;
|
|
68
|
-
}
|
|
69
111
|
|
|
70
|
-
|
|
71
|
-
const filterPassed = !filter || filter(this.router!, instance);
|
|
112
|
+
const filterPassed = !filter || filter(this.router!, instance);
|
|
72
113
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
114
|
+
if (pathMatched && filterPassed && instance[methodName]) {
|
|
115
|
+
await instance[methodName]({...re, pathData: pathData});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
await Promise.allSettled(ps);
|
|
119
|
+
}
|
|
120
|
+
} finally {
|
|
121
|
+
this._routeChangeInvocations--;
|
|
79
122
|
}
|
|
80
123
|
}
|
|
81
124
|
|
|
82
|
-
_connected(instance: any) {
|
|
83
|
-
// console.log('appmixin--> connected', this, instance);
|
|
125
|
+
async _connected(instance: any) {
|
|
84
126
|
if (instance) {
|
|
127
|
+
this._connectedInvocations++;
|
|
85
128
|
this._swc_connected_instance.add(instance);
|
|
129
|
+
|
|
130
|
+
if (this._childrenConnectedDoneInterval) {
|
|
131
|
+
clearInterval(this._childrenConnectedDoneInterval);
|
|
132
|
+
}
|
|
133
|
+
this._childrenConnectedDoneInterval = debounceTimeIntervalLock(
|
|
134
|
+
() => this._connectedInvocations === 0,
|
|
135
|
+
() => {
|
|
136
|
+
this._childrenConnectedDoneInterval = null;
|
|
137
|
+
this.config.onChildrenConnectedDone(this)
|
|
138
|
+
},
|
|
139
|
+
this.config?.childrenConnectedDoneCheckIntervalTime ?? 30,
|
|
140
|
+
{setInterval: window.setInterval, clearInterval: window.clearInterval}
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
|
|
86
144
|
if (this.simpleApplication) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
this.
|
|
145
|
+
try {
|
|
146
|
+
// await this._invokeOnConnectedSwcAppStarted(instance);
|
|
147
|
+
|
|
148
|
+
if (this.router && this._lastRouterEvent) {
|
|
149
|
+
await this._invokeRouteChangeSubscribers(instance, this._lastRouterEvent!);
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
throw e;
|
|
91
153
|
}
|
|
92
154
|
}
|
|
93
155
|
}
|
|
94
156
|
}
|
|
95
157
|
|
|
158
|
+
async _connectedDone(instance: any) {
|
|
159
|
+
try {
|
|
160
|
+
// 내부 연결 처리 로직이 있다면 여기에 추가
|
|
161
|
+
} finally {
|
|
162
|
+
this._connectedInvocations--;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
96
166
|
_disconnected(instance: any) {
|
|
167
|
+
// console.log('_disconnected', instance);
|
|
97
168
|
if (instance) {
|
|
98
169
|
this._swc_connected_instance.delete(instance);
|
|
99
|
-
this.
|
|
100
|
-
this._swc_notified_routes.delete(instance);
|
|
170
|
+
// this._swc_notified_routes.delete(instance);
|
|
101
171
|
}
|
|
102
172
|
}
|
|
103
173
|
|
|
104
174
|
async _handleRouteChange(route: RouterEventType) {
|
|
105
175
|
// Save last router event
|
|
106
176
|
this._lastRouterEvent = route;
|
|
107
|
-
if (route.triggerPoint === 'end') {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
177
|
+
// if (route.triggerPoint === 'end') {
|
|
178
|
+
// Iterate through all connected component instances
|
|
179
|
+
const swcConnectedInstance = Array.from(this._swc_connected_instance);
|
|
180
|
+
// console.log('routing handle-->', swcConnectedInstance)
|
|
181
|
+
const ps = swcConnectedInstance.map((instance: any) => this._invokeRouteChangeSubscribers(instance, route));
|
|
182
|
+
await Promise.allSettled(ps);
|
|
183
|
+
// }
|
|
113
184
|
}
|
|
114
185
|
|
|
115
186
|
async connect(config?: SwcAttributeConfigType) {
|
|
116
187
|
const swcConfig = {
|
|
117
188
|
routeType: 'element',
|
|
118
|
-
window: config
|
|
189
|
+
window: config?.window,
|
|
119
190
|
...config
|
|
120
191
|
} as SwcConfigType;
|
|
121
192
|
|
|
122
193
|
const mode = config?.connectMode || 'direct';
|
|
123
194
|
|
|
124
|
-
// console.log('-------mode', mode);
|
|
125
195
|
if (mode === 'direct') {
|
|
126
196
|
await this.__swc_engine.connect(swcConfig);
|
|
127
197
|
this.setAttribute('swc-connect-mode', 'direct');
|
|
@@ -134,21 +204,21 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
|
|
|
134
204
|
// 1. 현재 SSR 상태(화면)를 그대로 유지한 채로, 백그라운드용 클론을 만듭니다.
|
|
135
205
|
const clonedApp = this.cloneNode(mode === 'swap') as any; // clear-swap 모드면 자식 노드를 클론하지 않음(false)
|
|
136
206
|
clonedApp.style.display = 'none';
|
|
137
|
-
|
|
207
|
+
|
|
138
208
|
// 2. DOM에 클론을 몰래 붙입니다.
|
|
139
209
|
this.parentNode.insertBefore(clonedApp, this.nextSibling);
|
|
140
210
|
|
|
141
211
|
try {
|
|
142
212
|
// 3. 클론을 direct 모드로 연결(초기화/렌더링) 시킵니다.
|
|
143
|
-
await clonedApp.connect({
|
|
144
|
-
|
|
213
|
+
await clonedApp.connect({...(config || {}), connectMode: 'direct'});
|
|
214
|
+
|
|
145
215
|
// 4. 클론의 렌더링이 완전히 끝나면, 기존 SSR 화면(this)을 지우고 클론을 보여줍니다.
|
|
146
216
|
if (this.parentNode) {
|
|
147
217
|
this.parentNode.removeChild(this);
|
|
148
218
|
}
|
|
149
219
|
clonedApp.style.display = '';
|
|
150
220
|
clonedApp.setAttribute('swc-connect-mode', mode);
|
|
151
|
-
|
|
221
|
+
|
|
152
222
|
// ★ 매우 중요: 교체가 완료되었으므로 기존 앱(this)은 여기서 즉시 종료하여 불필요한 라우터/이벤트 구독을 막아야 합니다!
|
|
153
223
|
return;
|
|
154
224
|
} catch (e) {
|
|
@@ -164,12 +234,16 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
|
|
|
164
234
|
|
|
165
235
|
// 사파리일떄 예외이다 is 일때 polyfill되는데 이떄 부모부터 만들어지는게 아니라 자식부터 만들어진다 그래서 부모가 만들어질때 자식들이 이미 만들어져있어서 부모가 자식들을 등록해주는 형태로 강제로 등록해준다
|
|
166
236
|
this._connected_safari.forEach((instance: any) => {
|
|
167
|
-
|
|
237
|
+
// console.log('safari!!!!!!!!!!', instance)
|
|
238
|
+
this._connected(instance);
|
|
239
|
+
// this._swc_connected_instance.add(instance);
|
|
168
240
|
});
|
|
169
241
|
// Invoke @onConnectedSwcApp lifecycle methods on all connected component instances
|
|
170
242
|
// const hostSet = SwcUtils.getHostSet(this as any);
|
|
171
|
-
|
|
172
|
-
|
|
243
|
+
|
|
244
|
+
// const scis = Array.from(this._swc_connected_instance);
|
|
245
|
+
// await Promise.allSettled(scis.map(instance => this._invokeOnConnectedSwcAppStarted(instance)));
|
|
246
|
+
|
|
173
247
|
// this._swc_connected_instance.forEach((instance: any) => {
|
|
174
248
|
// this._invokeOnConnectedSwcAppStarted(instance);
|
|
175
249
|
// });
|
|
@@ -177,36 +251,42 @@ export function SwcAppMixin<T extends { new (...args: any[]): HTMLElement }>(Bas
|
|
|
177
251
|
// Subscribe to router changes after connect
|
|
178
252
|
if (!this._routerSubscription && this.router) {
|
|
179
253
|
const config = this.__swc_engine.config;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// console.log('
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
254
|
+
|
|
255
|
+
this._routerSubscription = this.router.observable.subscribe(async (route: RouterEventType) => {
|
|
256
|
+
// console.log('[SWC] Router event received:', route.triggerPoint);
|
|
257
|
+
if (route.triggerPoint === 'end') {
|
|
258
|
+
// 1. 모든 기존 연결된 자식들에게 라우트 이벤트 알림
|
|
259
|
+
await this._handleRouteChange(route);
|
|
260
|
+
}
|
|
186
261
|
});
|
|
262
|
+
|
|
187
263
|
// Navigate to initial path if specified
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
264
|
+
if (config?.path) {
|
|
265
|
+
// console.log('[DEBUG] Navigating to initial path:', config.path);
|
|
266
|
+
this.router.go(config.path);
|
|
267
|
+
}
|
|
191
268
|
}
|
|
192
269
|
}
|
|
193
270
|
|
|
194
|
-
async _invokeOnConnectedSwcAppStarted(instance: any) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
271
|
+
// async _invokeOnConnectedSwcAppStarted(instance: any) {
|
|
272
|
+
// this._swcAppStartedInvocations++;
|
|
273
|
+
// try {
|
|
274
|
+
// // 이미 시작된 인스턴스라면 스킵 (비동기 병렬 중복 호출 방지)
|
|
275
|
+
// if (this._swc_started_instances.has(instance)) return;
|
|
276
|
+
// this._swc_started_instances.add(instance);
|
|
277
|
+
//
|
|
278
|
+
// const startedMethods = findAllLifecycleMetadata(instance, ON_CONNECTED_SWC_APP_METADATA_KEY);
|
|
279
|
+
// if (startedMethods) {
|
|
280
|
+
// const ps = startedMethods.map(m => instance._invokeLifecycleMethod(m));
|
|
281
|
+
// await Promise.allSettled(ps);
|
|
282
|
+
// }
|
|
283
|
+
// } finally {
|
|
284
|
+
// this._swcAppStartedInvocations--;
|
|
285
|
+
// }
|
|
286
|
+
// }
|
|
208
287
|
|
|
209
288
|
connectedCallback() {
|
|
289
|
+
// this.innerHTML='';
|
|
210
290
|
// @ts-ignore
|
|
211
291
|
if (super.connectedCallback) super.connectedCallback();
|
|
212
292
|
|
package/src/elements/SwcAsync.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { changedAttributeThis } from '../decorators/changedAttributeThis';
|
|
2
2
|
import { SwcUtils } from '../utils/Utils';
|
|
3
3
|
import { FunctionUtils, ActionExpression } from '@dooboostore/core';
|
|
4
4
|
import { ConvertUtils } from '@dooboostore/core-web';
|
|
5
|
-
import {
|
|
5
|
+
import { attributeThis } from '../decorators';
|
|
6
6
|
|
|
7
7
|
class SwcAsync extends HTMLTemplateElement {
|
|
8
|
-
@
|
|
8
|
+
@attributeThis('value')
|
|
9
9
|
_value: any;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
resultValue?: any;
|
|
10
|
+
@attributeThis('replace-wrap-start')
|
|
11
|
+
_replaceWrapStart: string | null;
|
|
12
|
+
@attributeThis('replace-wrap-end')
|
|
13
|
+
_replaceWrapEnd: string | null; resultValue?: any;
|
|
15
14
|
|
|
16
15
|
get value(): boolean {
|
|
17
16
|
return this._value;
|
|
@@ -23,15 +22,15 @@ class SwcAsync extends HTMLTemplateElement {
|
|
|
23
22
|
|
|
24
23
|
private _nodes: Node[] = [];
|
|
25
24
|
|
|
26
|
-
@
|
|
25
|
+
@changedAttributeThis('value')
|
|
27
26
|
private setValue(valueAttr?: string | null) {
|
|
28
27
|
this.executeAsync(this._value);
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
@
|
|
32
|
-
private setReplaceWrap() {
|
|
33
|
-
|
|
34
|
-
}
|
|
30
|
+
// @changedAttributeThis('replace-wrap')
|
|
31
|
+
// private setReplaceWrap() {
|
|
32
|
+
// this.executeAsync(this._value);
|
|
33
|
+
// }
|
|
35
34
|
|
|
36
35
|
private executeAsync(result: any = this._value) {
|
|
37
36
|
if (result === undefined || result === null) {
|
|
@@ -57,14 +56,22 @@ class SwcAsync extends HTMLTemplateElement {
|
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
private replaceExpressions(html: string, groupArgs: any, context: any, wrap
|
|
61
|
-
|
|
59
|
+
private replaceExpressions(html: string, groupArgs: any, context: any, wrap: {start: string, end: string}): string {
|
|
60
|
+
let config: any = undefined;
|
|
61
|
+
if (wrap) {
|
|
62
|
+
config = {
|
|
63
|
+
expression: {
|
|
64
|
+
replace: { start: `${wrap.start}`, end: `${wrap.end}` },
|
|
65
|
+
callReturn: { start: `${wrap.start}=`, end: `${wrap.end}` },
|
|
66
|
+
call: { start: `${wrap.start}@`, end: `${wrap.end}` }
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
62
70
|
const ae = new ActionExpression(html, config);
|
|
63
|
-
const filterOptions = wrap ? { type: 'replace' as const, wrap } : 'replace';
|
|
64
71
|
const win = this.ownerDocument?.defaultView || window;
|
|
65
72
|
|
|
66
73
|
// @ts-ignore
|
|
67
|
-
for (const expr of ae.getExpressions(
|
|
74
|
+
for (const expr of ae.getExpressions('replace')) {
|
|
68
75
|
try {
|
|
69
76
|
const value = FunctionUtils.executeReturn({
|
|
70
77
|
script: ConvertUtils.decodeHtmlEntity(expr.script, win.document),
|
|
@@ -80,9 +87,9 @@ class SwcAsync extends HTMLTemplateElement {
|
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
refresh(state: string = 'default') {
|
|
83
|
-
console.log('rrrrrrrrrrrrrrrrr', state);
|
|
90
|
+
// console.log('rrrrrrrrrrrrrrrrr', state);
|
|
84
91
|
this.cleanup();
|
|
85
|
-
const portal = this
|
|
92
|
+
const portal = SwcUtils.getParentContainer(this);
|
|
86
93
|
if (!portal) return;
|
|
87
94
|
|
|
88
95
|
const win = this.ownerDocument?.defaultView || window;
|
|
@@ -91,15 +98,19 @@ class SwcAsync extends HTMLTemplateElement {
|
|
|
91
98
|
const t = this.content.querySelector(`template[is="swc-${state}"]`) as HTMLTemplateElement;
|
|
92
99
|
if (t) {
|
|
93
100
|
let htmlString = t.innerHTML;
|
|
94
|
-
const groupArgs = { ...helperSet, $value: this._value, $state: state };
|
|
101
|
+
const groupArgs = { ...helperSet, $value: this._value, $state: state, $templateHost: this };
|
|
95
102
|
|
|
96
|
-
htmlString = this.replaceExpressions(htmlString, groupArgs, this, this.
|
|
103
|
+
htmlString = this.replaceExpressions(htmlString, groupArgs, this, {start:this._replaceWrapStart ?? '{#{', end: this._replaceWrapEnd ?? '}#}'});
|
|
97
104
|
|
|
98
105
|
const temp = this.ownerDocument?.createElement('template') || document.createElement('template');
|
|
99
106
|
temp.innerHTML = htmlString;
|
|
100
107
|
const content = temp.content;
|
|
101
108
|
|
|
102
109
|
this._nodes = Array.from(content.childNodes);
|
|
110
|
+
this._nodes.forEach((node: any) => {
|
|
111
|
+
if (node instanceof HTMLElement) (node as any).__template_swc_host = this;
|
|
112
|
+
});
|
|
113
|
+
|
|
103
114
|
portal.insertBefore(content, this.nextSibling);
|
|
104
115
|
}
|
|
105
116
|
}
|