@dooboostore/simple-web-component 1.0.50 → 1.0.51

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 (241) hide show
  1. package/README.md +735 -354
  2. package/dist/cjs/SwcAppEngine.js.map +2 -2
  3. package/dist/cjs/decorators/addEventListener.js +64 -146
  4. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  5. package/dist/cjs/decorators/applyAttribute.js +36 -48
  6. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  7. package/dist/cjs/decorators/applyClass.js +9 -12
  8. package/dist/cjs/decorators/applyClass.js.map +2 -2
  9. package/dist/cjs/decorators/applyNode.js +14 -22
  10. package/dist/cjs/decorators/applyNode.js.map +2 -2
  11. package/dist/cjs/decorators/applyProperty.js +12 -42
  12. package/dist/cjs/decorators/applyProperty.js.map +2 -2
  13. package/dist/cjs/decorators/applySlot.js +3 -3
  14. package/dist/cjs/decorators/applySlot.js.map +2 -2
  15. package/dist/cjs/decorators/applyStyle.js +9 -12
  16. package/dist/cjs/decorators/applyStyle.js.map +2 -2
  17. package/dist/cjs/decorators/around.js +124 -0
  18. package/dist/cjs/decorators/around.js.map +7 -0
  19. package/dist/cjs/decorators/changedAttribute.js +40 -12
  20. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  21. package/dist/cjs/decorators/elementDefine.js +224 -195
  22. package/dist/cjs/decorators/elementDefine.js.map +3 -3
  23. package/dist/cjs/decorators/emitCustomEvent.js +14 -12
  24. package/dist/cjs/decorators/emitCustomEvent.js.map +2 -2
  25. package/dist/cjs/decorators/eventMedia.js +36 -8
  26. package/dist/cjs/decorators/eventMedia.js.map +2 -2
  27. package/dist/cjs/decorators/fetch.js +278 -0
  28. package/dist/cjs/decorators/fetch.js.map +7 -0
  29. package/dist/cjs/decorators/index.js +5 -2
  30. package/dist/cjs/decorators/index.js.map +2 -2
  31. package/dist/cjs/decorators/intersectionObserver.js +33 -13
  32. package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
  33. package/dist/cjs/decorators/lifecycles.js +11 -11
  34. package/dist/cjs/decorators/lifecycles.js.map +2 -2
  35. package/dist/cjs/decorators/mutationObserver.js +55 -39
  36. package/dist/cjs/decorators/mutationObserver.js.map +3 -3
  37. package/dist/cjs/decorators/parameter.js +92 -9
  38. package/dist/cjs/decorators/parameter.js.map +2 -2
  39. package/dist/cjs/decorators/publishSwcAppMessage.js +2 -2
  40. package/dist/cjs/decorators/publishSwcAppMessage.js.map +2 -2
  41. package/dist/cjs/decorators/query.js +11 -5
  42. package/dist/cjs/decorators/query.js.map +2 -2
  43. package/dist/cjs/decorators/requestAnimationFrame.js +7 -16
  44. package/dist/cjs/decorators/requestAnimationFrame.js.map +2 -2
  45. package/dist/cjs/decorators/resizeObserver.js +41 -17
  46. package/dist/cjs/decorators/resizeObserver.js.map +3 -3
  47. package/dist/cjs/decorators/setInterval.js +36 -25
  48. package/dist/cjs/decorators/setInterval.js.map +2 -2
  49. package/dist/cjs/decorators/setTimeout.js +36 -25
  50. package/dist/cjs/decorators/setTimeout.js.map +2 -2
  51. package/dist/cjs/decorators/state.js +13 -10
  52. package/dist/cjs/decorators/state.js.map +2 -2
  53. package/dist/cjs/decorators/{subscribeSwcAppMessageWhileConnected.js → subscribeSwcAppMessage.js} +20 -21
  54. package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +7 -0
  55. package/dist/cjs/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +23 -19
  56. package/dist/cjs/decorators/subscribeSwcAppRouteChange.js.map +7 -0
  57. package/dist/cjs/decorators/swcAppRoute.js +149 -0
  58. package/dist/cjs/decorators/swcAppRoute.js.map +7 -0
  59. package/dist/cjs/elements/SwcApp.js +70 -0
  60. package/dist/cjs/elements/SwcApp.js.map +2 -2
  61. package/dist/cjs/elements/SwcAppMixin.js +256 -83
  62. package/dist/cjs/elements/SwcAppMixin.js.map +3 -3
  63. package/dist/cjs/types/index.js +5 -1
  64. package/dist/cjs/types/index.js.map +2 -2
  65. package/dist/cjs/utils/Utils.js +36 -15
  66. package/dist/cjs/utils/Utils.js.map +2 -2
  67. package/dist/esm/SwcAppEngine.js.map +2 -2
  68. package/dist/esm/decorators/addEventListener.js +64 -146
  69. package/dist/esm/decorators/addEventListener.js.map +2 -2
  70. package/dist/esm/decorators/applyAttribute.js +36 -48
  71. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  72. package/dist/esm/decorators/applyClass.js +9 -12
  73. package/dist/esm/decorators/applyClass.js.map +2 -2
  74. package/dist/esm/decorators/applyNode.js +15 -23
  75. package/dist/esm/decorators/applyNode.js.map +2 -2
  76. package/dist/esm/decorators/applyProperty.js +12 -42
  77. package/dist/esm/decorators/applyProperty.js.map +2 -2
  78. package/dist/esm/decorators/applySlot.js +3 -3
  79. package/dist/esm/decorators/applySlot.js.map +2 -2
  80. package/dist/esm/decorators/applyStyle.js +9 -12
  81. package/dist/esm/decorators/applyStyle.js.map +2 -2
  82. package/dist/esm/decorators/around.js +105 -0
  83. package/dist/esm/decorators/around.js.map +7 -0
  84. package/dist/esm/decorators/changedAttribute.js +40 -12
  85. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  86. package/dist/esm/decorators/elementDefine.js +222 -193
  87. package/dist/esm/decorators/elementDefine.js.map +3 -3
  88. package/dist/esm/decorators/emitCustomEvent.js +15 -13
  89. package/dist/esm/decorators/emitCustomEvent.js.map +2 -2
  90. package/dist/esm/decorators/eventMedia.js +36 -8
  91. package/dist/esm/decorators/eventMedia.js.map +2 -2
  92. package/dist/esm/decorators/fetch.js +259 -0
  93. package/dist/esm/decorators/fetch.js.map +7 -0
  94. package/dist/esm/decorators/index.js +5 -2
  95. package/dist/esm/decorators/index.js.map +2 -2
  96. package/dist/esm/decorators/intersectionObserver.js +33 -13
  97. package/dist/esm/decorators/intersectionObserver.js.map +2 -2
  98. package/dist/esm/decorators/lifecycles.js +11 -11
  99. package/dist/esm/decorators/lifecycles.js.map +2 -2
  100. package/dist/esm/decorators/mutationObserver.js +55 -39
  101. package/dist/esm/decorators/mutationObserver.js.map +3 -3
  102. package/dist/esm/decorators/parameter.js +92 -9
  103. package/dist/esm/decorators/parameter.js.map +2 -2
  104. package/dist/esm/decorators/publishSwcAppMessage.js +2 -2
  105. package/dist/esm/decorators/publishSwcAppMessage.js.map +2 -2
  106. package/dist/esm/decorators/query.js +11 -5
  107. package/dist/esm/decorators/query.js.map +2 -2
  108. package/dist/esm/decorators/requestAnimationFrame.js +8 -17
  109. package/dist/esm/decorators/requestAnimationFrame.js.map +2 -2
  110. package/dist/esm/decorators/resizeObserver.js +41 -17
  111. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  112. package/dist/esm/decorators/setInterval.js +37 -26
  113. package/dist/esm/decorators/setInterval.js.map +2 -2
  114. package/dist/esm/decorators/setTimeout.js +37 -26
  115. package/dist/esm/decorators/setTimeout.js.map +2 -2
  116. package/dist/esm/decorators/state.js +13 -10
  117. package/dist/esm/decorators/state.js.map +2 -2
  118. package/dist/esm/decorators/subscribeSwcAppMessage.js +53 -0
  119. package/dist/esm/decorators/subscribeSwcAppMessage.js.map +7 -0
  120. package/dist/esm/decorators/{subscribeSwcAppRouteChangeWhileConnected.js → subscribeSwcAppRouteChange.js} +20 -16
  121. package/dist/esm/decorators/subscribeSwcAppRouteChange.js.map +7 -0
  122. package/dist/esm/decorators/swcAppRoute.js +130 -0
  123. package/dist/esm/decorators/swcAppRoute.js.map +7 -0
  124. package/dist/esm/elements/SwcApp.js +70 -0
  125. package/dist/esm/elements/SwcApp.js.map +2 -2
  126. package/dist/esm/elements/SwcAppMixin.js +258 -85
  127. package/dist/esm/elements/SwcAppMixin.js.map +3 -3
  128. package/dist/esm/types/index.js +5 -1
  129. package/dist/esm/types/index.js.map +2 -2
  130. package/dist/esm/utils/Utils.js +36 -15
  131. package/dist/esm/utils/Utils.js.map +2 -2
  132. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +1886 -999
  133. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  134. package/dist/types/SwcAppEngine.d.ts +1 -0
  135. package/dist/types/SwcAppEngine.d.ts.map +1 -1
  136. package/dist/types/decorators/addEventListener.d.ts +923 -960
  137. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  138. package/dist/types/decorators/applyAttribute.d.ts +26 -38
  139. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  140. package/dist/types/decorators/applyClass.d.ts +1 -3
  141. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  142. package/dist/types/decorators/applyNode.d.ts +15 -17
  143. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  144. package/dist/types/decorators/applyProperty.d.ts +25 -45
  145. package/dist/types/decorators/applyProperty.d.ts.map +1 -1
  146. package/dist/types/decorators/applyStyle.d.ts +1 -3
  147. package/dist/types/decorators/applyStyle.d.ts.map +1 -1
  148. package/dist/types/decorators/around.d.ts +87 -0
  149. package/dist/types/decorators/around.d.ts.map +1 -0
  150. package/dist/types/decorators/changedAttribute.d.ts +21 -1
  151. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  152. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  153. package/dist/types/decorators/emitCustomEvent.d.ts +0 -1
  154. package/dist/types/decorators/emitCustomEvent.d.ts.map +1 -1
  155. package/dist/types/decorators/eventMedia.d.ts +24 -1
  156. package/dist/types/decorators/eventMedia.d.ts.map +1 -1
  157. package/dist/types/decorators/fetch.d.ts +139 -0
  158. package/dist/types/decorators/fetch.d.ts.map +1 -0
  159. package/dist/types/decorators/index.d.ts +5 -2
  160. package/dist/types/decorators/index.d.ts.map +1 -1
  161. package/dist/types/decorators/intersectionObserver.d.ts +24 -11
  162. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
  163. package/dist/types/decorators/lifecycles.d.ts +8 -7
  164. package/dist/types/decorators/lifecycles.d.ts.map +1 -1
  165. package/dist/types/decorators/mutationObserver.d.ts +26 -13
  166. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  167. package/dist/types/decorators/parameter.d.ts +84 -6
  168. package/dist/types/decorators/parameter.d.ts.map +1 -1
  169. package/dist/types/decorators/publishSwcAppMessage.d.ts +0 -1
  170. package/dist/types/decorators/publishSwcAppMessage.d.ts.map +1 -1
  171. package/dist/types/decorators/query.d.ts +7 -7
  172. package/dist/types/decorators/query.d.ts.map +1 -1
  173. package/dist/types/decorators/requestAnimationFrame.d.ts +1 -1
  174. package/dist/types/decorators/requestAnimationFrame.d.ts.map +1 -1
  175. package/dist/types/decorators/resizeObserver.d.ts +26 -13
  176. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  177. package/dist/types/decorators/setInterval.d.ts +10 -0
  178. package/dist/types/decorators/setInterval.d.ts.map +1 -1
  179. package/dist/types/decorators/setTimeout.d.ts +10 -0
  180. package/dist/types/decorators/setTimeout.d.ts.map +1 -1
  181. package/dist/types/decorators/state.d.ts.map +1 -1
  182. package/dist/types/decorators/subscribeSwcAppMessage.d.ts +44 -0
  183. package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -0
  184. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts +60 -0
  185. package/dist/types/decorators/subscribeSwcAppRouteChange.d.ts.map +1 -0
  186. package/dist/types/decorators/swcAppRoute.d.ts +94 -0
  187. package/dist/types/decorators/swcAppRoute.d.ts.map +1 -0
  188. package/dist/types/elements/SwcApp.d.ts.map +1 -1
  189. package/dist/types/elements/SwcAppMixin.d.ts +423 -388
  190. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  191. package/dist/types/types/index.d.ts +43 -4
  192. package/dist/types/types/index.d.ts.map +1 -1
  193. package/dist/types/utils/Utils.d.ts +15 -5
  194. package/dist/types/utils/Utils.d.ts.map +1 -1
  195. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +1886 -999
  196. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  197. package/package.json +8 -6
  198. package/src/SwcAppEngine.ts +1 -0
  199. package/src/decorators/addEventListener.ts +102 -96
  200. package/src/decorators/applyAttribute.ts +76 -138
  201. package/src/decorators/applyClass.ts +8 -14
  202. package/src/decorators/applyNode.ts +33 -41
  203. package/src/decorators/applyProperty.ts +51 -99
  204. package/src/decorators/applySlot.ts +3 -3
  205. package/src/decorators/applyStyle.ts +8 -14
  206. package/src/decorators/around.ts +196 -0
  207. package/src/decorators/changedAttribute.ts +39 -15
  208. package/src/decorators/elementDefine.ts +270 -219
  209. package/src/decorators/emitCustomEvent.ts +17 -13
  210. package/src/decorators/eventMedia.ts +50 -9
  211. package/src/decorators/fetch.ts +454 -0
  212. package/src/decorators/index.ts +5 -2
  213. package/src/decorators/intersectionObserver.ts +38 -24
  214. package/src/decorators/lifecycles.ts +24 -22
  215. package/src/decorators/mutationObserver.ts +71 -52
  216. package/src/decorators/parameter.ts +145 -14
  217. package/src/decorators/publishSwcAppMessage.ts +3 -4
  218. package/src/decorators/query.ts +22 -14
  219. package/src/decorators/requestAnimationFrame.ts +10 -19
  220. package/src/decorators/resizeObserver.ts +50 -29
  221. package/src/decorators/setInterval.ts +37 -26
  222. package/src/decorators/setTimeout.ts +37 -26
  223. package/src/decorators/state.ts +19 -13
  224. package/src/decorators/subscribeSwcAppMessage.ts +106 -0
  225. package/src/decorators/subscribeSwcAppRouteChange.ts +131 -0
  226. package/src/decorators/swcAppRoute.ts +231 -0
  227. package/src/elements/SwcApp.ts +40 -10
  228. package/src/elements/SwcAppMixin.ts +330 -101
  229. package/src/types/index.ts +38 -5
  230. package/src/utils/Utils.ts +50 -18
  231. package/dist/cjs/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  232. package/dist/cjs/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  233. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js +0 -54
  234. package/dist/esm/decorators/subscribeSwcAppMessageWhileConnected.js.map +0 -7
  235. package/dist/esm/decorators/subscribeSwcAppRouteChangeWhileConnected.js.map +0 -7
  236. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts +0 -23
  237. package/dist/types/decorators/subscribeSwcAppMessageWhileConnected.d.ts.map +0 -1
  238. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts +0 -31
  239. package/dist/types/decorators/subscribeSwcAppRouteChangeWhileConnected.d.ts.map +0 -1
  240. package/src/decorators/subscribeSwcAppMessageWhileConnected.ts +0 -91
  241. package/src/decorators/subscribeSwcAppRouteChangeWhileConnected.ts +0 -107
@@ -30,6 +30,43 @@ var import_SwcAppEngine = require("../SwcAppEngine");
30
30
  var import_core = require("@dooboostore/core");
31
31
  var import_core_web = require("@dooboostore/core-web");
32
32
  var import_Utils = require("../utils/Utils");
33
+ const routeStateOf = (instance) => instance.__swc_routeState ?? (instance.__swc_routeState = /* @__PURE__ */ new Map());
34
+ const routeParamValues = (sp, pathDataAll) => {
35
+ const queryAll = Object.fromEntries([...new Set(sp.keys())].map((k) => [k, sp.getAll(k)]));
36
+ const pick = (all, at) => Object.fromEntries(Object.entries(all).map(([k, v]) => [k, at === "first" ? v[0] : v[v.length - 1]]));
37
+ const lastOf = (v) => v && v.length ? v[v.length - 1] : void 0;
38
+ const firstQuery = (k) => sp.get(k);
39
+ const firstPath = (k) => pathDataAll[k]?.[0];
40
+ return {
41
+ swcAppRouteQueryParam: firstQuery,
42
+ swcAppRouteFirstQueryParam: firstQuery,
43
+ swcAppRouteLastQueryParam: (k) => lastOf(sp.getAll(k)) ?? null,
44
+ swcAppRouteQueryParams: (k) => sp.getAll(k),
45
+ swcAppRouteQueryParamObject: pick(queryAll, "first"),
46
+ swcAppRouteFirstQueryParamObject: pick(queryAll, "first"),
47
+ swcAppRouteLastQueryParamObject: pick(queryAll, "last"),
48
+ swcAppRouteQueryParamsObject: queryAll,
49
+ swcAppRouteURLSearchParams: sp,
50
+ swcAppRoutePathVariable: firstPath,
51
+ swcAppRouteFirstPathVariable: firstPath,
52
+ swcAppRouteLastPathVariable: (k) => lastOf(pathDataAll[k]),
53
+ swcAppRoutePathVariables: (k) => pathDataAll[k] ?? [],
54
+ swcAppRoutePathVariableObject: pick(pathDataAll, "first"),
55
+ swcAppRouteFirstPathVariableObject: pick(pathDataAll, "first"),
56
+ swcAppRouteLastPathVariableObject: pick(pathDataAll, "last"),
57
+ swcAppRoutePathVariablesObject: pathDataAll
58
+ };
59
+ };
60
+ const matchRoute = (pathOption, instance, re) => {
61
+ let pattern = typeof pathOption === "function" ? pathOption(instance) : pathOption;
62
+ if (!pattern) return { pathData: {}, pathDataAll: {} };
63
+ const path = re.path || "/";
64
+ for (const p of Array.isArray(pattern) ? pattern : [pattern]) {
65
+ const pathData = import_Utils.SwcUtils.parsePathPattern(p, path);
66
+ if (pathData !== null) return { pathData, pathDataAll: import_Utils.SwcUtils.parsePathPatternAll(p, path) ?? {} };
67
+ }
68
+ return null;
69
+ };
33
70
  const isSSR = (i) => {
34
71
  return i.hasAttribute("swc-use-ssr");
35
72
  };
@@ -40,13 +77,18 @@ const removeSSRAttribute = (i) => {
40
77
  i.removeAttribute("swc-use-ssr");
41
78
  };
42
79
  function SwcAppMixin(Base) {
43
- return class SwcAppMixinClass extends Base {
44
- constructor(...args) {
45
- super(...args);
80
+ class SwcAppMixinClass extends Base {
81
+ constructor() {
82
+ super(...arguments);
46
83
  __publicField(this, "__swc_engine", new import_SwcAppEngine.SwcAppEngine(this));
84
+ __publicField(this, "_swcId");
47
85
  __publicField(this, "_swc_connected_instance", /* @__PURE__ */ new Set());
48
86
  __publicField(this, "_routerSubscription");
49
87
  __publicField(this, "_lastRouterEvent");
88
+ // replay 옵션으로 발행된 타입별 마지막 메시지 1개 보관
89
+ __publicField(this, "_replayedMessages", /* @__PURE__ */ new Map());
90
+ // 코드 구독(observeMessage)용 live 스트림. 데코레이터 구독과 같은 publishMessage에서 흘러나옴.
91
+ __publicField(this, "_messageSubject", new import_core.Subject());
50
92
  __publicField(this, "_routeChangeInvocations", 0);
51
93
  __publicField(this, "_connectedInvocations", 0);
52
94
  __publicField(this, "_childrenRouteChangedInterval");
@@ -57,7 +99,8 @@ function SwcAppMixin(Base) {
57
99
  * 부모가 자식들을 강제로 등록해주는 형태로 처리
58
100
  */
59
101
  __publicField(this, "_connected_safari_and_standby", []);
60
- console.log("[SWC-APP-MIXIN] constructor");
102
+ // connect() 전에 붙은 자식들이 기다리는 곳 — connect() 가 엔진을 띄운 뒤 깨운다
103
+ __publicField(this, "_appReadyWaiters", []);
61
104
  }
62
105
  get simpleApplication() {
63
106
  return this.__swc_engine.simpleApplication;
@@ -68,7 +111,8 @@ function SwcAppMixin(Base) {
68
111
  get router() {
69
112
  return this.__swc_engine?.router;
70
113
  }
71
- async _invokeRouteChangeSubscribers(instance, re) {
114
+ // phase: 'live'(기본, 전체 방송) | 'connected' | 'connectedDone' (replay, 해당 trigger만)
115
+ async _invokeRouteChangeSubscribers(instance, re, phase = "live") {
72
116
  if (instance.isConnected === false) return;
73
117
  this._routeChangeInvocations++;
74
118
  if (this._childrenRouteChangedInterval) {
@@ -85,56 +129,51 @@ function SwcAppMixin(Base) {
85
129
  intervalConfig
86
130
  );
87
131
  try {
88
- const routeChangeSubscribers = (0, import_decorators.getSubscribeSwcAppRouteChangeWhileConnectedMetadata)(instance);
132
+ const routeChangeSubscribers = (0, import_decorators.getSubscribeSwcAppRouteChangeMetadata)(instance);
89
133
  if (routeChangeSubscribers.length > 0) {
134
+ const state = routeStateOf(instance);
135
+ let stopped = false;
90
136
  for (const metadata of routeChangeSubscribers) {
137
+ if (phase !== "live" && (metadata.options?.trigger ?? "connected") !== phase) continue;
138
+ const on = metadata.options?.on ?? "match";
139
+ if (on === "beforeLeave") continue;
91
140
  const methodName = metadata.propertyKey;
92
- let pathPattern = metadata.options?.path;
93
- const filter = metadata.options?.filter;
94
141
  const extractValue = (v) => {
95
- const keyToUse = metadata.options?.valueKey ?? import_decorators.SUBSCRIBE_SWC_APP_ROUTE_CHANGE_WHILE_CONNECTED_METADATA_KEY;
142
+ const keyToUse = metadata.options?.valueKey ?? import_decorators.SUBSCRIBE_SWC_APP_ROUTE_CHANGE_METADATA_KEY;
96
143
  if (v && typeof v === "object" && keyToUse in v) {
97
144
  return v[keyToUse];
98
145
  }
99
146
  return v;
100
147
  };
101
- if (typeof pathPattern === "function") {
102
- pathPattern = pathPattern(instance);
103
- }
104
- let pathMatched = false;
105
- let pathData = null;
106
- if (!pathPattern) {
107
- pathMatched = true;
108
- pathData = {};
109
- } else if (Array.isArray(pathPattern)) {
110
- for (const pattern of pathPattern) {
111
- const data = import_Utils.SwcUtils.parsePathPattern(pattern, re.path || "/");
112
- if (data !== null) {
113
- pathMatched = true;
114
- pathData = data;
115
- break;
116
- }
117
- }
118
- } else {
119
- pathData = import_Utils.SwcUtils.parsePathPattern(pathPattern, re.path || "/");
120
- pathMatched = pathData !== null;
148
+ const match = matchRoute(metadata.options?.path, instance, re);
149
+ const prev = state.get(methodName);
150
+ const signature = match ? JSON.stringify([re.path ?? "", re.search ?? ""]) : "";
151
+ state.set(methodName, match ? { matched: true, signature, pathData: match.pathData, pathDataAll: match.pathDataAll } : { matched: false, signature: "" });
152
+ const shouldRun = on === "match" ? !!match : on === "enter" ? !!match && !prev?.matched : on === "update" ? !!match && !!prev?.matched && prev.signature !== signature : on === "leave" ? !match && !!prev?.matched : false;
153
+ if (stopped || !shouldRun || !instance[methodName]) continue;
154
+ const pathData = match ? match.pathData : prev?.pathData ?? {};
155
+ const pathDataAll = match ? match.pathDataAll : prev?.pathDataAll ?? {};
156
+ const filter = metadata.options?.filter;
157
+ const instanceHelperHostSet = import_Utils.SwcUtils.getHelperAndHostSet(instance, this.config.window);
158
+ const filterPassed = !filter || await filter(this.router, { helper: instanceHelperHostSet, currentThis: instance });
159
+ if (!filterPassed) continue;
160
+ const before = metadata.options?.before;
161
+ const finaly = metadata.options?.finally;
162
+ const beforeReturn = before ? await before(this.router, { helper: instanceHelperHostSet, currentThis: instance }) : void 0;
163
+ const routeEventValue = { ...re, pathData };
164
+ const args = this._buildRouteArgs(instance, methodName, routeEventValue, pathDataAll, beforeReturn);
165
+ let rawResult, error;
166
+ try {
167
+ rawResult = await instance[methodName](...args);
168
+ } catch (e) {
169
+ error = e;
170
+ } finally {
171
+ if (finaly) await finaly(this.router, { helper: instanceHelperHostSet, currentThis: instance }, { args, result: rawResult, error });
121
172
  }
122
- const hostSet = import_Utils.SwcUtils.getHelperAndHostSet(this.config.window, this);
123
- const filterPassed = !filter || filter(this.router, { helper: hostSet, currentThis: instance });
124
- if (pathMatched && filterPassed && instance[methodName]) {
125
- const routeEventValue = { ...re, pathData };
126
- const instanceHelperHostSet = import_Utils.SwcUtils.getHelperAndHostSet(this.config.window, instance);
127
- const instanceHelperSet = import_Utils.SwcUtils.getHelperSet(this.config.window);
128
- const args = (0, import_decorators.buildSwcParameterArgs)(instance, methodName, {
129
- routerEvent: routeEventValue,
130
- hostSet: instanceHelperHostSet,
131
- helperHostSet: instanceHelperHostSet,
132
- helperSet: instanceHelperSet
133
- }, [routeEventValue]);
134
- const result = extractValue(await instance[methodName](...args));
135
- if (result !== void 0 && result !== null) {
136
- break;
137
- }
173
+ if (error) throw error;
174
+ const result = extractValue(rawResult);
175
+ if (result !== void 0 && result !== null) {
176
+ stopped = true;
138
177
  }
139
178
  }
140
179
  }
@@ -148,20 +187,75 @@ function SwcAppMixin(Base) {
148
187
  this._routeChangeInvocations = Math.max(0, this._routeChangeInvocations - 1);
149
188
  }
150
189
  }
190
+ /** 라우트 핸들러 인자: @swcAppRouterEvent / host 계열 / @routeChangeBeforeReturn / 라우트 파라미터(query·path 변수) */
191
+ _buildRouteArgs(instance, methodName, routeEventValue, pathDataAll, beforeReturn) {
192
+ const instanceHelperHostSet = import_Utils.SwcUtils.getHelperAndHostSet(instance, this.config.window);
193
+ const sp = routeEventValue.searchParams ?? new URLSearchParams(routeEventValue.search ?? "");
194
+ return (0, import_decorators.buildSwcParameterArgs)(
195
+ instance,
196
+ methodName,
197
+ {
198
+ swcAppRouterEvent: routeEventValue,
199
+ hostSet: instanceHelperHostSet,
200
+ helperHostSet: instanceHelperHostSet,
201
+ helperSet: import_Utils.SwcUtils.getHelperSet(this.config.window),
202
+ routeChangeBeforeReturn: beforeReturn,
203
+ ...routeParamValues(sp, pathDataAll)
204
+ },
205
+ [routeEventValue]
206
+ );
207
+ }
208
+ /**
209
+ * on: 'beforeLeave' 구독을 라우터 가드로 등록. 지금 경로는 맞고 다음 경로는 안 맞을 때 핸들러를 부르고,
210
+ * false 를 리턴하면 이동을 취소한다. 요소가 떨어지면 _disconnected 에서 해제.
211
+ */
212
+ _registerLeaveGuards(instance) {
213
+ if (!this.router?.addLeaveGuard) return;
214
+ instance.__swc_leaveGuardOffs?.forEach((off) => off());
215
+ instance.__swc_leaveGuardOffs = (0, import_decorators.getSubscribeSwcAppRouteChangeMetadata)(instance).filter((m) => m.options?.on === "beforeLeave").map(
216
+ (metadata) => this.router.addLeaveGuard(async (to, from) => {
217
+ if (instance.isConnected === false || !instance[metadata.propertyKey]) return true;
218
+ const fromMatch = matchRoute(metadata.options?.path, instance, from);
219
+ if (!fromMatch || matchRoute(metadata.options?.path, instance, to)) return true;
220
+ const filter = metadata.options?.filter;
221
+ const helper = import_Utils.SwcUtils.getHelperAndHostSet(instance, this.config.window);
222
+ if (filter && !await filter(this.router, { helper, currentThis: instance })) return true;
223
+ const beforeReturn = metadata.options?.before ? await metadata.options.before(this.router, { helper, currentThis: instance }) : void 0;
224
+ const routeEventValue = { ...from, pathData: fromMatch.pathData, to };
225
+ const args = this._buildRouteArgs(instance, metadata.propertyKey, routeEventValue, fromMatch.pathDataAll, beforeReturn);
226
+ let result, error;
227
+ try {
228
+ result = await instance[metadata.propertyKey](...args);
229
+ } catch (e) {
230
+ error = e;
231
+ } finally {
232
+ if (metadata.options?.finally) await metadata.options.finally(this.router, { helper, currentThis: instance }, { args, result, error });
233
+ }
234
+ if (error) throw error;
235
+ return result !== false;
236
+ })
237
+ );
238
+ }
151
239
  async _connected(instance, option) {
152
240
  if (instance) {
153
241
  if (!this.simpleApplication && !this.config) {
154
- this._connected_safari_and_standby.push(instance);
155
- return;
242
+ if (instance === this) {
243
+ this._connected_safari_and_standby.push(instance);
244
+ return;
245
+ }
246
+ await new Promise((resolve) => this._appReadyWaiters.push(resolve));
156
247
  }
157
248
  this.config.onConnectedChildBefore?.(instance);
158
249
  if (!option?.noIncrements) {
159
250
  this._connectedInvocations++;
160
251
  }
161
252
  this._swc_connected_instance.add(instance);
253
+ const gen = instance.__swc_connectGen;
254
+ const stale = () => instance.__swc_connectGen !== gen;
162
255
  const connectedSwcAppCallBacks = (0, import_decorators.findAllLifecycleMetadata)(instance, import_decorators.ON_CONNECTED_SWC_APP_METADATA_KEY);
163
256
  for (let connectedSwcAppCallBack of connectedSwcAppCallBacks) {
164
257
  await instance?._invokeLifecycleMethod?.(connectedSwcAppCallBack.propertyKey);
258
+ if (stale()) return this;
165
259
  }
166
260
  if (this._childrenConnectedDoneInterval) {
167
261
  this.config.window.clearInterval(this._childrenConnectedDoneInterval);
@@ -179,14 +273,16 @@ function SwcAppMixin(Base) {
179
273
  if (this.simpleApplication) {
180
274
  try {
181
275
  if (this.router && this._lastRouterEvent) {
182
- await this._invokeRouteChangeSubscribers(instance, this._lastRouterEvent);
276
+ await this._invokeRouteChangeSubscribers(instance, this._lastRouterEvent, "connected");
183
277
  }
184
278
  } catch (e) {
185
279
  throw e;
186
280
  }
187
281
  }
282
+ if (stale()) return this;
283
+ if (this.simpleApplication) this._registerLeaveGuards(instance);
284
+ this._replayMessagesTo(instance);
188
285
  const isBrowser = import_core_web.ValidUtils.isBrowser();
189
- console.log("------>", isBrowser, this.config?.ssr);
190
286
  if (!isBrowser && this.config?.ssr) {
191
287
  setSSRAttribute(instance);
192
288
  } else {
@@ -196,8 +292,19 @@ function SwcAppMixin(Base) {
196
292
  this.config.onConnectedChildAfter?.(instance);
197
293
  return this;
198
294
  }
199
- async _connectedDone(instance) {
295
+ async _connectedDone(instance, option) {
200
296
  try {
297
+ if (option?.aborted) return;
298
+ this._replayMessagesTo(instance, "connectedDone");
299
+ if (this.simpleApplication) {
300
+ try {
301
+ if (this.router && this._lastRouterEvent) {
302
+ await this._invokeRouteChangeSubscribers(instance, this._lastRouterEvent, "connectedDone");
303
+ }
304
+ } catch (e) {
305
+ throw e;
306
+ }
307
+ }
201
308
  } finally {
202
309
  this._connectedInvocations = Math.max(0, this._connectedInvocations - 1);
203
310
  }
@@ -205,6 +312,9 @@ function SwcAppMixin(Base) {
205
312
  _disconnected(instance) {
206
313
  if (instance) {
207
314
  this._swc_connected_instance.delete(instance);
315
+ instance.__swc_leaveGuardOffs?.forEach((off) => off());
316
+ instance.__swc_leaveGuardOffs = void 0;
317
+ instance.__swc_routeState = void 0;
208
318
  this.config?.onDisconnectedChildAfter?.(instance);
209
319
  }
210
320
  }
@@ -215,28 +325,24 @@ function SwcAppMixin(Base) {
215
325
  await Promise.allSettled(ps);
216
326
  }
217
327
  async connect(config) {
218
- console.log("[SWC-MIXIN] connect");
219
328
  const swcConfig = {
220
329
  routeType: "element",
221
330
  window: config?.window,
222
331
  ...config
223
332
  };
224
333
  await this.__swc_engine.connect(swcConfig);
334
+ this._appReadyWaiters.splice(0).forEach((resolve) => resolve());
225
335
  this._connected_safari_and_standby.forEach((instance) => {
226
336
  this._connected(instance, { noIncrements: true });
227
337
  });
228
338
  if (!this._routerSubscription && this.router) {
229
- const config2 = this.__swc_engine.config;
230
339
  this._routerSubscription = this.router.observable.subscribe(async (route) => {
231
- console.log("[SWC-MIXIN] Router event received:", route.triggerPoint);
232
340
  if (route.triggerPoint === "end") {
233
341
  await this._handleRouteChange(route);
234
342
  }
235
343
  });
236
- if (config2?.path) {
237
- console.log("[DEBUG] Navigating to initial path:", config2.path);
238
- }
239
344
  }
345
+ await this._invokeHook("onSwcAppConnected");
240
346
  }
241
347
  connectedCallback() {
242
348
  super.connectedCallback?.();
@@ -247,7 +353,7 @@ function SwcAppMixin(Base) {
247
353
  const userConfig = import_core.FunctionUtils.executeReturn({
248
354
  script: configStr,
249
355
  context: this,
250
- args: import_Utils.SwcUtils.getHelperAndHostSet(win, this)
356
+ args: import_Utils.SwcUtils.getHelperAndHostSet(this, win)
251
357
  });
252
358
  if (userConfig instanceof Promise) {
253
359
  userConfig.then((resolvedConfig) => {
@@ -265,6 +371,7 @@ function SwcAppMixin(Base) {
265
371
  this._connected(this);
266
372
  this.__swc_engine?.config?.onConnected?.(this);
267
373
  this._connectedDone(this);
374
+ void this._invokeHook("onConnected").catch((e) => console.error("[SWC-MIXIN] onConnected error:", e));
268
375
  }
269
376
  disconnectedCallback() {
270
377
  super.disconnectedCallback?.();
@@ -274,6 +381,7 @@ function SwcAppMixin(Base) {
274
381
  this.__swc_engine.disconnect();
275
382
  this.__swc_engine?.config?.onDisconnected?.(this);
276
383
  this._disconnected(this);
384
+ void this._invokeHook("onDisconnected").catch((e) => console.error("[SWC-MIXIN] onDisconnected error:", e));
277
385
  }
278
386
  async routing(path) {
279
387
  await this.router?.go(path);
@@ -288,41 +396,106 @@ function SwcAppMixin(Base) {
288
396
  this.router?.reload();
289
397
  }
290
398
  publishMessage(message) {
399
+ if (message.type) {
400
+ const buf = [...this._replayedMessages.get(message.type) ?? [], message];
401
+ this._replayedMessages.set(message.type, buf.slice(-Math.max(1, this.config?.messageReplayBufferSize ?? 10)));
402
+ }
291
403
  this._swc_connected_instance.forEach((instance) => {
292
404
  this._invokeMessageSubscribers(instance, message);
293
405
  });
406
+ this._messageSubject.next(message);
407
+ }
408
+ connectedElements() {
409
+ return Array.from(this._swc_connected_instance);
410
+ }
411
+ observeMessage(typeOrOptions, options) {
412
+ const { type, subject } = typeof typeOrOptions === "string" ? { ...options, type: typeOrOptions } : { ...typeOrOptions };
413
+ return new import_core.Observable((subscriber) => {
414
+ if (type && (subject === "behavior" || subject === "replay")) {
415
+ const buf = this._replayedMessages.get(type) ?? [];
416
+ (subject === "behavior" ? buf.slice(-1) : buf).forEach((m) => subscriber.next(m));
417
+ }
418
+ const sub = this._messageSubject.subscribe((m) => {
419
+ if (!type || m.type === type) subscriber.next(m);
420
+ });
421
+ return () => sub.unsubscribe();
422
+ });
423
+ }
424
+ // hook 실행 + @inject 파라미터 DI 해결 (host 본체 포함.
425
+ // _invokeLifecycleMethod는 host/hostSet 상황 분기가 달라 호스트 본체에서 주입이 안 됨)
426
+ async _invokeHook(methodName) {
427
+ const fn = this[methodName];
428
+ if (typeof fn !== "function") return;
429
+ const manager = this.simpleApplication?.simstanceManager;
430
+ if (!manager) {
431
+ return fn.call(this);
432
+ }
433
+ return manager.executeBindParameterSimPromise({ target: this, targetKey: methodName });
434
+ }
435
+ // 신규 연결 인스턴스 1곳에만 버퍼 재생. 구독자별 subject 선언 기준:
436
+ // - 'behavior': 마지막 1개 / 'replay': 버퍼 전체 시간순 / 미지정·'subject': live만 (재생 안 함)
437
+ // - trigger 'connectedDone'인 구독은 _connectedDone(render 완료 후)에서 재생. phase로 구분.
438
+ // 이미 연결된 인스턴스는 publishMessage 때 live로 받으므로 여기 오지 않음.
439
+ _replayMessagesTo(instance, phase = "connected") {
440
+ const subs = (0, import_decorators.getSubscribeSwcAppMessageMetadata)(instance);
441
+ if (!subs || !Array.isArray(subs)) return;
442
+ const seen = /* @__PURE__ */ new Set();
443
+ subs.forEach((meta) => {
444
+ const type = meta.messageType;
445
+ if (!type || seen.has(type)) return;
446
+ seen.add(type);
447
+ if ((meta.trigger ?? "connected") !== phase) return;
448
+ const buf = this._replayedMessages.get(type) ?? [];
449
+ if (meta.subject === "behavior") {
450
+ const last = buf[buf.length - 1];
451
+ if (last) this._invokeMessageSubscribers(instance, last);
452
+ } else if (meta.subject === "replay") {
453
+ buf.forEach((msg) => this._invokeMessageSubscribers(instance, msg));
454
+ }
455
+ });
294
456
  }
295
457
  _invokeMessageSubscribers(instance, message) {
296
- const messageSubscribers = (0, import_decorators.getSubscribeSwcAppMessageWhileConnectedMetadata)(instance);
458
+ const messageSubscribers = (0, import_decorators.getSubscribeSwcAppMessageMetadata)(instance);
297
459
  if (messageSubscribers && Array.isArray(messageSubscribers)) {
298
460
  messageSubscribers.forEach((metadata) => {
299
- const methodName = metadata.propertyKey;
300
- const messageType = metadata.messageType;
301
- const filter = metadata.filter;
302
- let typeMatched = false;
303
- if (!messageType) {
304
- typeMatched = true;
305
- } else if (message.type === messageType) {
306
- typeMatched = true;
307
- }
308
- let filterMatched = true;
309
- if (filter && typeMatched) {
310
- filterMatched = filter(message, instance);
311
- }
312
- if (typeMatched && filterMatched && typeof instance[methodName] === "function") {
313
- const instanceHelperHostSet = import_Utils.SwcUtils.getHelperAndHostSet(this.config.window, instance);
314
- const instanceHelperSet = import_Utils.SwcUtils.getHelperSet(this.config.window);
315
- const args = (0, import_decorators.buildSwcParameterArgs)(instance, methodName, {
316
- appMessage: message,
317
- hostSet: instanceHelperHostSet,
318
- helperHostSet: instanceHelperHostSet,
319
- helperSet: instanceHelperSet
320
- }, [message]);
321
- instance[methodName](...args);
322
- }
461
+ void this._runMessageSubscriber(instance, message, metadata).catch((e) => console.error("[SWC] subscribeSwcAppMessage error:", e));
323
462
  });
324
463
  }
325
464
  }
326
- };
465
+ async _runMessageSubscriber(instance, message, metadata) {
466
+ const methodName = metadata.propertyKey;
467
+ const messageType = metadata.messageType;
468
+ const { filter, before, finally: finaly } = metadata;
469
+ const typeMatched = !messageType || message.type === messageType;
470
+ if (!typeMatched) return;
471
+ if (filter && !await filter(message, instance)) return;
472
+ if (typeof instance[methodName] !== "function") return;
473
+ const instanceHelperHostSet = import_Utils.SwcUtils.getHelperAndHostSet(instance, this.config.window);
474
+ const instanceHelperSet = import_Utils.SwcUtils.getHelperSet(this.config.window);
475
+ const beforeReturn = before ? await before(message, instance) : void 0;
476
+ const args = (0, import_decorators.buildSwcParameterArgs)(
477
+ instance,
478
+ methodName,
479
+ {
480
+ appMessage: message,
481
+ hostSet: instanceHelperHostSet,
482
+ helperHostSet: instanceHelperHostSet,
483
+ helperSet: instanceHelperSet,
484
+ appMessageBeforeReturn: beforeReturn
485
+ },
486
+ [message]
487
+ );
488
+ let result, error;
489
+ try {
490
+ result = await instance[methodName](...args);
491
+ } catch (e) {
492
+ error = e;
493
+ } finally {
494
+ if (finaly) await finaly(message, instance, { args, result, error });
495
+ }
496
+ if (error) throw error;
497
+ }
498
+ }
499
+ return SwcAppMixinClass;
327
500
  }
328
501
  //# sourceMappingURL=SwcAppMixin.js.map