@dooboostore/simple-web-component 1.0.53 → 1.0.55

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 (121) hide show
  1. package/README.md +308 -56
  2. package/dist/cjs/decorators/addEventListener.js +37 -14
  3. package/dist/cjs/decorators/addEventListener.js.map +2 -2
  4. package/dist/cjs/decorators/applyAttribute.js +6 -3
  5. package/dist/cjs/decorators/applyAttribute.js.map +2 -2
  6. package/dist/cjs/decorators/applyClass.js +18 -2
  7. package/dist/cjs/decorators/applyClass.js.map +2 -2
  8. package/dist/cjs/decorators/applyNode.js +24 -2
  9. package/dist/cjs/decorators/applyNode.js.map +2 -2
  10. package/dist/cjs/decorators/changedAttribute.js +2 -5
  11. package/dist/cjs/decorators/changedAttribute.js.map +2 -2
  12. package/dist/cjs/decorators/elementDefine.js +13 -2
  13. package/dist/cjs/decorators/elementDefine.js.map +2 -2
  14. package/dist/cjs/decorators/eventMedia.js +2 -5
  15. package/dist/cjs/decorators/eventMedia.js.map +2 -2
  16. package/dist/cjs/decorators/fetch.js +216 -82
  17. package/dist/cjs/decorators/fetch.js.map +3 -3
  18. package/dist/cjs/decorators/index.js +1 -0
  19. package/dist/cjs/decorators/index.js.map +2 -2
  20. package/dist/cjs/decorators/intersectionObserver.js +3 -6
  21. package/dist/cjs/decorators/intersectionObserver.js.map +2 -2
  22. package/dist/cjs/decorators/mutationObserver.js +3 -6
  23. package/dist/cjs/decorators/mutationObserver.js.map +2 -2
  24. package/dist/cjs/decorators/parameter.js +197 -33
  25. package/dist/cjs/decorators/parameter.js.map +3 -3
  26. package/dist/cjs/decorators/persistState.js +474 -0
  27. package/dist/cjs/decorators/persistState.js.map +7 -0
  28. package/dist/cjs/decorators/resizeObserver.js +3 -6
  29. package/dist/cjs/decorators/resizeObserver.js.map +2 -2
  30. package/dist/cjs/decorators/setInterval.js +2 -5
  31. package/dist/cjs/decorators/setInterval.js.map +2 -2
  32. package/dist/cjs/decorators/setTimeout.js +2 -5
  33. package/dist/cjs/decorators/setTimeout.js.map +2 -2
  34. package/dist/cjs/decorators/subscribeSwcAppMessage.js.map +1 -1
  35. package/dist/cjs/elements/SwcAppMixin.js +50 -2
  36. package/dist/cjs/elements/SwcAppMixin.js.map +2 -2
  37. package/dist/esm/decorators/addEventListener.js +38 -15
  38. package/dist/esm/decorators/addEventListener.js.map +2 -2
  39. package/dist/esm/decorators/applyAttribute.js +6 -3
  40. package/dist/esm/decorators/applyAttribute.js.map +2 -2
  41. package/dist/esm/decorators/applyClass.js +18 -2
  42. package/dist/esm/decorators/applyClass.js.map +2 -2
  43. package/dist/esm/decorators/applyNode.js +24 -2
  44. package/dist/esm/decorators/applyNode.js.map +2 -2
  45. package/dist/esm/decorators/changedAttribute.js +3 -6
  46. package/dist/esm/decorators/changedAttribute.js.map +2 -2
  47. package/dist/esm/decorators/elementDefine.js +15 -4
  48. package/dist/esm/decorators/elementDefine.js.map +2 -2
  49. package/dist/esm/decorators/eventMedia.js +3 -6
  50. package/dist/esm/decorators/eventMedia.js.map +2 -2
  51. package/dist/esm/decorators/fetch.js +216 -82
  52. package/dist/esm/decorators/fetch.js.map +3 -3
  53. package/dist/esm/decorators/index.js +1 -0
  54. package/dist/esm/decorators/index.js.map +2 -2
  55. package/dist/esm/decorators/intersectionObserver.js +4 -7
  56. package/dist/esm/decorators/intersectionObserver.js.map +2 -2
  57. package/dist/esm/decorators/mutationObserver.js +4 -7
  58. package/dist/esm/decorators/mutationObserver.js.map +2 -2
  59. package/dist/esm/decorators/parameter.js +197 -33
  60. package/dist/esm/decorators/parameter.js.map +3 -3
  61. package/dist/esm/decorators/persistState.js +455 -0
  62. package/dist/esm/decorators/persistState.js.map +7 -0
  63. package/dist/esm/decorators/resizeObserver.js +4 -7
  64. package/dist/esm/decorators/resizeObserver.js.map +2 -2
  65. package/dist/esm/decorators/setInterval.js +3 -6
  66. package/dist/esm/decorators/setInterval.js.map +2 -2
  67. package/dist/esm/decorators/setTimeout.js +3 -6
  68. package/dist/esm/decorators/setTimeout.js.map +2 -2
  69. package/dist/esm/decorators/subscribeSwcAppMessage.js.map +1 -1
  70. package/dist/esm/elements/SwcAppMixin.js +51 -3
  71. package/dist/esm/elements/SwcAppMixin.js.map +2 -2
  72. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js +4470 -3620
  73. package/dist/esm-bundle/dooboostore-simple-web-component.esm.js.map +4 -4
  74. package/dist/types/decorators/addEventListener.d.ts +15 -0
  75. package/dist/types/decorators/addEventListener.d.ts.map +1 -1
  76. package/dist/types/decorators/applyAttribute.d.ts +1 -0
  77. package/dist/types/decorators/applyAttribute.d.ts.map +1 -1
  78. package/dist/types/decorators/applyClass.d.ts.map +1 -1
  79. package/dist/types/decorators/applyNode.d.ts +14 -0
  80. package/dist/types/decorators/applyNode.d.ts.map +1 -1
  81. package/dist/types/decorators/changedAttribute.d.ts.map +1 -1
  82. package/dist/types/decorators/elementDefine.d.ts.map +1 -1
  83. package/dist/types/decorators/eventMedia.d.ts.map +1 -1
  84. package/dist/types/decorators/fetch.d.ts +52 -31
  85. package/dist/types/decorators/fetch.d.ts.map +1 -1
  86. package/dist/types/decorators/index.d.ts +1 -0
  87. package/dist/types/decorators/index.d.ts.map +1 -1
  88. package/dist/types/decorators/intersectionObserver.d.ts.map +1 -1
  89. package/dist/types/decorators/mutationObserver.d.ts.map +1 -1
  90. package/dist/types/decorators/parameter.d.ts +169 -31
  91. package/dist/types/decorators/parameter.d.ts.map +1 -1
  92. package/dist/types/decorators/persistState.d.ts +66 -0
  93. package/dist/types/decorators/persistState.d.ts.map +1 -0
  94. package/dist/types/decorators/resizeObserver.d.ts.map +1 -1
  95. package/dist/types/decorators/setInterval.d.ts.map +1 -1
  96. package/dist/types/decorators/setTimeout.d.ts.map +1 -1
  97. package/dist/types/decorators/subscribeSwcAppMessage.d.ts +1 -1
  98. package/dist/types/decorators/subscribeSwcAppMessage.d.ts.map +1 -1
  99. package/dist/types/elements/SwcAppMixin.d.ts +12 -0
  100. package/dist/types/elements/SwcAppMixin.d.ts.map +1 -1
  101. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js +4470 -3620
  102. package/dist/umd-bundle/dooboostore-simple-web-component.umd.js.map +4 -4
  103. package/package.json +1 -1
  104. package/src/decorators/addEventListener.ts +23 -15
  105. package/src/decorators/applyAttribute.ts +8 -3
  106. package/src/decorators/applyClass.ts +22 -2
  107. package/src/decorators/applyNode.ts +44 -2
  108. package/src/decorators/changedAttribute.ts +3 -4
  109. package/src/decorators/elementDefine.ts +19 -7
  110. package/src/decorators/eventMedia.ts +3 -6
  111. package/src/decorators/fetch.ts +270 -140
  112. package/src/decorators/index.ts +1 -0
  113. package/src/decorators/intersectionObserver.ts +4 -5
  114. package/src/decorators/mutationObserver.ts +4 -5
  115. package/src/decorators/parameter.ts +326 -42
  116. package/src/decorators/persistState.ts +408 -0
  117. package/src/decorators/resizeObserver.ts +4 -5
  118. package/src/decorators/setInterval.ts +3 -4
  119. package/src/decorators/setTimeout.ts +3 -4
  120. package/src/decorators/subscribeSwcAppMessage.ts +1 -1
  121. package/src/elements/SwcAppMixin.ts +64 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-web-component",
3
- "version": "1.0.53",
3
+ "version": "1.0.55",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -1172,6 +1172,22 @@ export const eventToggleAll = toggleAliases.all;
1172
1172
  export const eventToggleAppHost = toggleAliases.appHost;
1173
1173
  export const eventToggleWindow = toggleAliases.window;
1174
1174
  export const eventToggleDocument = toggleAliases.document;
1175
+ const visibilitychangeAliases = makeTypedEventAliases<Event>('visibilitychange');
1176
+ export const eventVisibilitychange = visibilitychangeAliases.base;
1177
+ export const eventVisibilitychangeDelegateLight = visibilitychangeAliases.delegateLight;
1178
+ export const eventVisibilitychangeDelegateShadow = visibilitychangeAliases.delegateShadow;
1179
+ export const eventVisibilitychangeDelegateAll = visibilitychangeAliases.delegateAll;
1180
+ export const eventVisibilitychangeDelegate = visibilitychangeAliases.delegate;
1181
+ export const eventVisibilitychangeMutationLight = visibilitychangeAliases.mutationLight;
1182
+ export const eventVisibilitychangeMutationShadow = visibilitychangeAliases.mutationShadow;
1183
+ export const eventVisibilitychangeMutationAll = visibilitychangeAliases.mutationAll;
1184
+ export const eventVisibilitychangeMutation = visibilitychangeAliases.mutation;
1185
+ export const eventVisibilitychangeLight = visibilitychangeAliases.light;
1186
+ export const eventVisibilitychangeShadow = visibilitychangeAliases.shadow;
1187
+ export const eventVisibilitychangeAll = visibilitychangeAliases.all;
1188
+ export const eventVisibilitychangeAppHost = visibilitychangeAliases.appHost;
1189
+ export const eventVisibilitychangeWindow = visibilitychangeAliases.window;
1190
+ export const eventVisibilitychangeDocument = visibilitychangeAliases.document;
1175
1191
  export const getAddEventListenerMetadata = (target: any): AddEventListenerMetadata<Event>[] | undefined => {
1176
1192
  const constructor = typeof target === 'function' ? target : target.constructor;
1177
1193
  return ReflectUtils.findAllMetadata<any[]>(ADD_EVENT_LISTENER_METADATA_KEY, constructor).flat();
@@ -1184,7 +1200,7 @@ import { ElementDefineLifeCycler, MutationObserverSetEntry, OnConnectedResult }
1184
1200
  import { Subject } from '@dooboostore/core';
1185
1201
  import { debounceTime, distinctUntilChanged, throttleTime } from '@dooboostore/core/message/operators';
1186
1202
  import { SwcUtils } from '../utils/Utils';
1187
- import { buildSwcParameterArgs } from './parameter';
1203
+ import { buildSwcParameterArgs, buildCommonKindValues } from './parameter';
1188
1204
 
1189
1205
  export interface BoundListenerEntry {
1190
1206
  target: EventTarget;
@@ -1240,16 +1256,12 @@ export class EventListenerLifeCycler implements ElementDefineLifeCycler {
1240
1256
  if (options.stopPropagation) event.stopPropagation();
1241
1257
  if (options.stopImmediatePropagation) event.stopImmediatePropagation();
1242
1258
  if (options.preventDefault) event.preventDefault();
1243
- const currentHostSet = SwcUtils.getHostSet(inst);
1244
- const legacyArgs = [event, { currentHostSet, $matchedElement: matchedElement }, { event, ...currentHostSet, $el: target, $root: target }];
1245
- const currentHelperSet = SwcUtils.getHelperSet(currentWin);
1246
- const currentHelperHostSet = { ...currentHelperSet, ...currentHostSet, $this: inst };
1259
+ const common = buildCommonKindValues(inst, currentWin);
1260
+ const legacyArgs = [event, { currentHostSet: common.hostSet, $matchedElement: matchedElement }, { event, ...common.hostSet, $el: target, $root: target }];
1247
1261
  const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, meta.propertyKey, {
1262
+ ...common,
1248
1263
  eventObject: event,
1249
1264
  matchedElement,
1250
- hostSet: currentHostSet,
1251
- helperHostSet: currentHelperHostSet,
1252
- helperSet: currentHelperSet,
1253
1265
  eventBeforeReturn: beforeReturn
1254
1266
  }, legacyArgs);
1255
1267
  // before를 먼저 돌려 그 리턴값을 @eventBeforeReturn 으로 주입. before엔 (아직 자기 리턴 전이라
@@ -1394,16 +1406,12 @@ export class EventListenerLifeCycler implements ElementDefineLifeCycler {
1394
1406
  if (m.options.stopPropagation) event.stopPropagation();
1395
1407
  if (m.options.stopImmediatePropagation) event.stopImmediatePropagation();
1396
1408
  if (m.options.preventDefault) event.preventDefault();
1397
- const hs = SwcUtils.getHostSet(inst);
1398
- const legacyArgs = [event, { ...hs, $matchedElement: matchedEl }, { event, ...hs, $el: matchedEl, $root: br }];
1399
- const helperSetForMatch = SwcUtils.getHelperSet(currentWin);
1400
- const helperHostSetForMatch = { ...helperSetForMatch, ...hs, $this: inst };
1409
+ const common = buildCommonKindValues(inst, currentWin);
1410
+ const legacyArgs = [event, { ...common.hostSet, $matchedElement: matchedEl }, { event, ...common.hostSet, $el: matchedEl, $root: br }];
1401
1411
  const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, m.propertyKey, {
1412
+ ...common,
1402
1413
  eventObject: event,
1403
1414
  matchedElement: matchedEl,
1404
- hostSet: hs,
1405
- helperHostSet: helperHostSetForMatch,
1406
- helperSet: helperSetForMatch,
1407
1415
  eventBeforeReturn: beforeReturn
1408
1416
  }, legacyArgs);
1409
1417
  // before를 먼저 돌려 그 리턴값을 @eventBeforeReturn 으로 주입.
@@ -369,6 +369,7 @@ export function attribute(selectorOrAttributeOrTarget?: AttributeSelector | Attr
369
369
 
370
370
  /**
371
371
  * @removeAttribute - 메서드 실행 시 엘리먼트 속성 제거 (반환값 그대로 통과).
372
+ * 반환값과 상관없이 지운다. valueKey 를 줬을 때만 그 키 값이 truthy 인지 본다 (@removeNode 와 같은 규칙).
372
373
  * 라우트 구독처럼 값을 리턴하면 안 되는 곳에서 @attribute 에 null 을 리턴하는 대신 명시적으로 사용.
373
374
  *
374
375
  * Usage:
@@ -382,16 +383,20 @@ export function removeAttribute(selector: AttributeSelector, attributeName: stri
382
383
  const original = descriptor.value;
383
384
  descriptor.value = function (...args: any[]) {
384
385
  const res = (original as any).apply(this, args);
385
- const doRemove = () => {
386
+ // 이름에 이미 의도가 있으니 반환값과 상관없이 지운다. valueKey 를 줬을 때만 그 키 값이 truthy 인지 본다.
387
+ const doRemove = (v: any) => {
388
+ const vk = options?.valueKey;
389
+ const go = vk !== undefined ? (v && typeof v === 'object' ? v[vk] : undefined) : true;
390
+ if (!go) return;
386
391
  resolveAttributeTargets(this, selector, options ?? {}).forEach((el) => el.removeAttribute(attributeName));
387
392
  };
388
393
  if (res instanceof Promise) {
389
394
  return res.then((v: any) => {
390
- doRemove();
395
+ doRemove(v);
391
396
  return v;
392
397
  });
393
398
  }
394
- doRemove();
399
+ doRemove(res);
395
400
  return res;
396
401
  };
397
402
  return descriptor;
@@ -208,11 +208,31 @@ function createClassDecorator(action: ClassAction) {
208
208
  return resolvedValue;
209
209
  };
210
210
 
211
+ // 클래스 이름을 선언에 적은 add/remove/toggle 은 이름에 이미 의도가 있다 — 반환값과 상관없이 실행.
212
+ // valueKey 를 줬을 때만 그 키 값을 본다: add/remove 는 truthy 일 때만, toggle 은 true/false 로 켜고 끔.
213
+ // toggle 은 valueKey 없이 반환값이 없으면 그냥 토글, true/false 를 반환하면 그대로 켜고 끈다.
214
+ const fixedName = typeof classMap === 'string' && (action === 'add' || action === 'remove' || action === 'toggle') ? classMap : undefined;
215
+ const applyFixed = (raw: any) => {
216
+ const vk = finalOptions.valueKey;
217
+ const v = vk !== undefined ? (raw && typeof raw === 'object' ? raw[vk] : undefined) : action === 'toggle' ? raw : true;
218
+ if (vk !== undefined && (action === 'toggle' ? v === undefined : !v)) return;
219
+ const win = (this as any).ownerDocument?.defaultView || window;
220
+ const hostSet = { ...SwcUtils.getHelperAndHostSet(this as unknown as HTMLElement), $this: this };
221
+ getTargetElements(selector, this, win, finalOptions.root || 'auto').forEach(el => {
222
+ if (finalOptions.filter && !finalOptions.filter(el, v, { currentThis: this, helper: hostSet })) return;
223
+ if (action === 'add') el.classList.add(fixedName!);
224
+ else if (action === 'remove') el.classList.remove(fixedName!);
225
+ else if (v === undefined) el.classList.toggle(fixedName!);
226
+ else el.classList.toggle(fixedName!, !!v);
227
+ });
228
+ };
229
+ const run = (raw: any) => (fixedName ? applyFixed(raw) : handleResult(extractValue(raw)));
230
+
211
231
  if (res instanceof Promise) {
212
232
  // 자기 몫(valueKey)만 적용하고 원래 반환값은 그대로 위로 넘긴다 — 위에 쌓인 다른 아웃풋도 자기 키를 찾게
213
- return res.then((v: any) => { handleResult(extractValue(v)); return v; });
233
+ return res.then((v: any) => { run(v); return v; });
214
234
  } else {
215
- handleResult(extractValue(res));
235
+ run(res);
216
236
  return res;
217
237
  }
218
238
  };
@@ -86,6 +86,12 @@ const applyToDom = (currentThis: any, targetEl: HTMLElement, res: Node | string
86
86
  targetEl.replaceChildren();
87
87
  return [];
88
88
  }
89
+
90
+ // remove: 대상 자체를 DOM에서 뗀다. $this 처럼 shadow root 로 잡혔으면 그 주인 엘리먼트를 뗀다.
91
+ if (pos === 'remove') {
92
+ (targetEl instanceof win.ShadowRoot ? (targetEl as any).host : targetEl).remove();
93
+ return [];
94
+ }
89
95
 
90
96
  const doc = win.document;
91
97
  const hostSet = SwcUtils.getHelperAndHostSet(currentThis);
@@ -230,8 +236,20 @@ export function applyNode(selectorOrOptions: ApplyNodeSelector | ApplyNodeOption
230
236
  return v;
231
237
  };
232
238
 
239
+ // remove / clearChildren: 이름에 이미 의도가 있으니 반환값과 상관없이 실행한다.
240
+ // valueKey 를 줬을 때만 그 키 값이 truthy 인지 본다 (키가 없거나 falsy 면 안 함).
241
+ const decide = (raw: any) => {
242
+ if (options.position === 'remove' || options.position === 'clearChildren') {
243
+ if (options.valueKey === undefined) return true;
244
+ return raw && typeof raw === 'object' ? raw[options.valueKey] : undefined;
245
+ }
246
+ return extractValue(raw);
247
+ };
248
+
233
249
  const runApply = (target: any, val: any) => {
234
250
  const pos = options.position || 'beforeEnd';
251
+ // remove / clearChildren: valueKey 로 뽑은 값이 falsy 면 안 한다 (valueKey 없으면 decide 가 항상 true)
252
+ if ((pos === 'remove' || pos === 'clearChildren') && !val) return;
235
253
  // Delegate HTML/node processing to applyToDom which centralizes
236
254
  // processing. runApply should not call processHtml itself to avoid
237
255
  // duplicate processing.
@@ -253,13 +271,13 @@ export function applyNode(selectorOrOptions: ApplyNodeSelector | ApplyNodeOption
253
271
 
254
272
  if (res instanceof Promise) {
255
273
  return res.then(finalRes => {
256
- const extracted = extractValue(finalRes);
274
+ const extracted = decide(finalRes);
257
275
  fallbackNodes.forEach((it: any)=>it.remove());
258
276
  if (extracted !== undefined && targetEl) runApply(targetEl, extracted);
259
277
  return finalRes;
260
278
  });
261
279
  } else {
262
- const extracted = extractValue(res);
280
+ const extracted = decide(res);
263
281
  if (extracted !== undefined && targetEl) runApply(targetEl, extracted);
264
282
  return res;
265
283
  }
@@ -299,6 +317,7 @@ export function replaceChildren(selectorOrOptions?: ApplyNodeSelector | Omit<App
299
317
 
300
318
  /**
301
319
  * @clearChildrenNode decorator - clears all children of target element
320
+ * 반환값과 상관없이 비운다. valueKey 를 줬을 때만 그 키 값이 truthy 일 때 비운다 (@removeNode 와 같은 규칙).
302
321
  *
303
322
  * Overloads:
304
323
  * - clearChildrenNode(selector, options) - Clear children of specific selector
@@ -323,6 +342,29 @@ export function clearChildrenNode(selectorOrOptions?: ApplyNodeSelector | Omit<A
323
342
  // Alias for clearChildrenNode
324
343
  export const clearNode = clearChildrenNode;
325
344
 
345
+ /**
346
+ * @removeNode - 메서드가 끝나면 대상 엘리먼트를 DOM에서 제거한다. 반환값은 그대로 통과.
347
+ * - 이름에 의도가 있으니 반환값과 상관없이 지운다.
348
+ * - valueKey 를 줬을 때만 그 키 값을 본다: truthy 면 지우고, 키가 없거나 falsy 면 안 지운다.
349
+ * 선택자에 맞는 첫 번째 엘리먼트를 지운다. 선택자가 없거나 '$this' 면 자기 자신을 지운다.
350
+ *
351
+ * - @removeNode('.toast') / @removeNode('.toast', { valueKey: 'close' })
352
+ * - @removeNode({ valueKey: 'done' }) ($this)
353
+ * - @removeNode ($this, bare)
354
+ */
355
+ export function removeNode(selector: ApplyNodeSelector, options?: Omit<ApplyNodeOptions, 'position'>): MethodDecorator;
356
+ export function removeNode(options: Omit<ApplyNodeOptions, 'position'>): MethodDecorator;
357
+ export function removeNode(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void;
358
+ export function removeNode(selectorOrOptions?: ApplyNodeSelector | Omit<ApplyNodeOptions, 'position'> | Object, maybeOptions?: Omit<ApplyNodeOptions, 'position'> | string | symbol, descriptor?: PropertyDescriptor): MethodDecorator | PropertyDescriptor | void {
359
+ if (descriptor !== undefined && (typeof maybeOptions === 'symbol' || typeof maybeOptions === 'string')) {
360
+ return applyNode({position: 'remove'})(selectorOrOptions as Object, maybeOptions, descriptor);
361
+ }
362
+ if (typeof selectorOrOptions === 'string' || typeof selectorOrOptions === 'function') {
363
+ return applyNode(selectorOrOptions as any, {...maybeOptions as Omit<ApplyNodeOptions, 'position'>, position: 'remove'});
364
+ }
365
+ return applyNode({...selectorOrOptions as Omit<ApplyNodeOptions, 'position'>, position: 'remove'});
366
+ }
367
+
326
368
  /**
327
369
  * @innerHtmlNode decorator - sets innerHTML of target element
328
370
  *
@@ -86,7 +86,7 @@ export const convertAttributeValue = (val: any, type?: typeof Number | typeof Bo
86
86
  import { ElementDefineLifeCycler, HelperHostSet } from '../types';
87
87
  import { getAttributeValue, convertValue } from './applyAttribute';
88
88
  import { SwcUtils } from '../utils/Utils';
89
- import { buildSwcParameterArgs } from './parameter';
89
+ import { buildSwcParameterArgs, buildCommonKindValues } from './parameter';
90
90
 
91
91
  export class ChangedAttributeLifeCycler implements ElementDefineLifeCycler {
92
92
  private attrChangeMap: Map<string, ChangedAttributeThisMetadata[]> | null = null;
@@ -134,11 +134,10 @@ export class ChangedAttributeLifeCycler implements ElementDefineLifeCycler {
134
134
  void (async () => {
135
135
  const helper = SwcUtils.getHelperAndHostSet(inst);
136
136
  if (opts.filter && !(await opts.filter(value, { currentThis: inst, helper }))) return;
137
- const hostSet = SwcUtils.getHostSet(inst);
138
- const helperSet = SwcUtils.getHelperSet(helperHostSet.$w);
137
+ const common = buildCommonKindValues(inst, helperHostSet.$w);
139
138
  const legacyArgs = [value, old, name, helper];
140
139
  const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, meta.propertyKey, {
141
- hostSet, helperHostSet: helper, helperSet, changedAttributeBeforeReturn: beforeReturn
140
+ ...common, changedAttributeBeforeReturn: beforeReturn
142
141
  }, [...legacyArgs, beforeReturn]);
143
142
  let args = buildArgs(undefined);
144
143
  if (opts.before) { const br = await opts.before(value, { currentThis: inst, helper }); args = buildArgs(br); }
@@ -12,7 +12,7 @@ import {SwcUtils} from '../utils/Utils';
12
12
  import {DOM_EVENT_NAMES, HTML_TAG_ENTRIES} from '../config/config';
13
13
  import {SituationTypeContainer, SituationTypeContainers} from '@dooboostore/simple-boot/decorators/inject/Inject';
14
14
  import {FirstCheckMaker} from '@dooboostore/simple-boot';
15
- import {buildSwcParameterArgs, getParameterMetadata} from './parameter';
15
+ import {buildSwcParameterArgs, buildDomStorageKindValues, getParameterMetadata} from './parameter';
16
16
  import {ElementDefineLifeCycler, HelperHostSet, HostSet, InjectSituationType, IntersectionObserverSet, MutationObserverSet, MutationObserverSetEntry, ObserverScope, OnConnectedResult, ResizeObserverSet, ResizeObserverSetEntry, SwcRootType} from '../types';
17
17
  import {ConvertUtils, ElementApply} from '@dooboostore/core-web';
18
18
  import {isSSR} from "../elements/SwcAppMixin";
@@ -25,7 +25,7 @@ import {SetIntervalLifeCycler} from "./setInterval";
25
25
  import {SetTimeoutLifeCycler} from "./setTimeout";
26
26
  import {RequestAnimationFrameLifeCycler} from "./requestAnimationFrame";
27
27
  import {EventMediaLifeCycler} from "./eventMedia";
28
- import {FetchLifeCycler} from "./fetch";
28
+ import {FetchLifeCycler, assertFetchFields} from "./fetch";
29
29
 
30
30
  // --- Core Interfaces & Types ---
31
31
 
@@ -266,11 +266,17 @@ const setupPrototype = (proto: any, win: Window) => {
266
266
  const useHostSet = hostSet ?? SwcUtils.getHelperAndHostSet(this);
267
267
  const app = useHostSet?.$appHost?.simpleApplication;
268
268
 
269
- // @hostSet/@helperHostSet/@helperSet(parameter.ts)를 위한 값. lifecycle 메서드는
270
- // event/matched 개념이 없으므로 이 세 가지만 채운다.
269
+ // @hostSet/@helperHostSet/@helperSet/@swcAppRouter(parameter.ts)를 위한 값. lifecycle 메서드는
270
+ // event/matched 개념이 없으므로 이것들만 채운다.
271
271
  const helperSetValue = SwcUtils.getHelperSet(win);
272
272
  const helperHostSetValue = {...helperSetValue, ...useHostSet, $this: this};
273
- const kindValues = {hostSet: useHostSet, helperHostSet: helperHostSetValue, helperSet: helperSetValue};
273
+ const kindValues = {
274
+ hostSet: useHostSet, helperHostSet: helperHostSetValue, helperSet: helperSetValue,
275
+ swcAppRouter: useHostSet?.$appHost?.router,
276
+ swcAppSimpleApplication: useHostSet?.$appHost?.simpleApplication,
277
+ swcAppHost: useHostSet?.$appHost,
278
+ ...buildDomStorageKindValues(this, win)
279
+ };
274
280
 
275
281
  // console.log('---->hh',app, this, methodName);
276
282
  if (app) {
@@ -288,12 +294,16 @@ const setupPrototype = (proto: any, win: Window) => {
288
294
  // 해석보다 먼저 처리되고(firstCheckMaker), 그 외 파라미터는 기존처럼 @Inject/타입
289
295
  // 기반으로 정상 해석된다 — 같은 메서드에서 두 방식을 섞어 써도 된다.
290
296
  // swc 파라미터 데코레이터가 붙은 자리는 DI 로 넘기지 않는다. lifecycle 이 못 채우는 kind
291
- // (예: @fetchSettled — @fetch 가 나중에 채움)는 null. undefined 를 돌려주면
297
+ // (예: @fetchPromise — @fetch 가 채움)는 null. undefined 를 돌려주면
292
298
  // "처리 안 함"으로 보고 DI 가 파라미터 타입(Object 등)을 resolve 하려다 SimNoSuch 로 죽는다.
293
299
  const firstCheckMaker: FirstCheckMaker = ({target, targetKey}, token, idx) => {
294
300
  const saves = getParameterMetadata(target, targetKey!);
295
301
  const found = saves.find(s => s.index === idx);
296
- return found ? ((kindValues as any)[found.kind] ?? null) : undefined;
302
+ if (!found) return undefined;
303
+ const value = (kindValues as any)[found.kind];
304
+ // 키를 받는 kind(@querySelectorParam/@attributeParam/@local·session·cookieParam 등)는
305
+ // buildSwcParameterArgs와 동일하게 value(key)로 해석한다 — 아니면 리졸버 함수 자체가 주입된다.
306
+ return (found.key !== undefined && typeof value === 'function' ? value(found.key) : value) ?? null;
297
307
  };
298
308
 
299
309
  return app.simstanceManager.executeBindParameterSim(
@@ -384,6 +394,8 @@ export const elementDefine =
384
394
  if (!metadata.window) {
385
395
  throw new Error('window is required');
386
396
  }
397
+ // 필드 @fetch 에 다른 데코레이터가 같이 붙었으면 정의 시점에 바로 알린다
398
+ assertFetchFields(constructor);
387
399
 
388
400
  let extendsTagName = metadata.extends;
389
401
  if (!extendsTagName) {
@@ -1,7 +1,7 @@
1
1
  import { ReflectUtils } from '@dooboostore/core';
2
2
  import { ElementDefineLifeCycler, HelperHostSet } from '../types';
3
3
  import { SwcUtils } from '../utils/Utils';
4
- import { buildSwcParameterArgs } from './parameter';
4
+ import { buildSwcParameterArgs, buildCommonKindValues } from './parameter';
5
5
 
6
6
  export const EVENT_MEDIA_METADATA_KEY = Symbol.for('simple-web-component:event-media');
7
7
 
@@ -70,14 +70,11 @@ export class EventMediaLifeCycler implements ElementDefineLifeCycler {
70
70
  try {
71
71
  const helper = SwcUtils.getHelperAndHostSet(inst);
72
72
  if (meta.filter && !(await meta.filter(e as MediaQueryListEvent, { currentThis: inst, helper }))) return;
73
- const hostSet = SwcUtils.getHostSet(inst);
74
- const helperSet = SwcUtils.getHelperSet(win);
73
+ const common = buildCommonKindValues(inst, win);
75
74
  const legacyArgs = [e, helperHostSet];
76
75
  const buildArgs = (beforeReturn: any) => buildSwcParameterArgs(inst, meta.propertyKey, {
76
+ ...common,
77
77
  eventObject: e,
78
- hostSet,
79
- helperHostSet: helper,
80
- helperSet,
81
78
  eventMediaBeforeReturn: beforeReturn
82
79
  }, legacyArgs);
83
80
  // before를 먼저 돌려 그 리턴값을 @eventMediaBeforeReturn 으로 주입.