@ihabdevteam/core 0.342.0 → 0.344.0

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 (34) hide show
  1. package/CHANGELOG.md +103 -2
  2. package/dist/components.cjs.js +40 -40
  3. package/dist/hooks.cjs.js +5 -3
  4. package/dist/i18n.cjs.js +1 -1
  5. package/dist/ihabdevteam-core.cjs.js +188 -188
  6. package/dist/ihabdevteam-core.d.ts +2 -2
  7. package/dist/packages/core/src/components/Training/AudioPlayerWaveForm.js +4 -3
  8. package/dist/packages/core/src/components/Training/TrainingPagePopup.js +14 -1
  9. package/dist/packages/core/src/hooks/useCacheManagement.js +15 -5
  10. package/dist/packages/core/src/hooks/useDailyTrainingSelection.js +16 -4
  11. package/dist/packages/core/src/hooks/useEditableList.js +11 -2
  12. package/dist/packages/core/src/hooks/useFocusTrap.js +11 -1
  13. package/dist/packages/core/src/hooks/useIcon.js +7 -1
  14. package/dist/packages/core/src/hooks/useInlineSvg.js +47 -18
  15. package/dist/packages/core/src/hooks/useListControls.js +11 -7
  16. package/dist/packages/core/src/hooks/usePasswordChange.js +15 -1
  17. package/dist/packages/core/src/hooks/useSoundCompassExam.js +5 -3
  18. package/dist/packages/core/src/hooks/useTablePaging.js +10 -5
  19. package/dist/packages/core/src/hooks/useTrainingSessionLog.js +8 -4
  20. package/dist/packages/core/src/hooks/useVisitAllPanel.d.ts +5 -4
  21. package/dist/packages/core/src/hooks/useVisitAllPanel.js +11 -3
  22. package/dist/packages/core/src/hooks/useWordImage.js +15 -7
  23. package/dist/packages/core/src/hooks/useWordMeanings.js +36 -9
  24. package/dist/packages/core/src/hooks/useWordTrainingFilter.js +9 -5
  25. package/dist/packages/core/src/utils/getTrainingData.js +9 -2
  26. package/dist/packages/core/src/utils/imageConfig.js +52 -17
  27. package/dist/packages/core/src/utils/prefetchChunk.js +10 -3
  28. package/dist/packages/core/src/utils/speak.js +51 -27
  29. package/dist/packages/core/src/utils/ttsConfig.js +10 -3
  30. package/dist/packages/core/src/utils/wordPairIndex.js +16 -1
  31. package/dist/packages/core/src/version.d.ts +1 -1
  32. package/dist/packages/core/src/version.js +1 -1
  33. package/dist/utils.cjs.js +4 -4
  34. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,12 +7,113 @@ All notable changes to this project will be documented in this file.
7
7
  > 적은 글이라, 지금 이름으로 고쳐 놓으면 그 시절에 그 이름으로 받은 사람이
8
8
  > 제 이야기를 못 찾는다.
9
9
 
10
+ ## 0.344.0 — 조용히 틀리던 자리 스무 곳
11
+
12
+ **다른 세션이 10분마다 훑어 찾아 고친 것을 받아 검토하고 냈다.** 알맹이 23파일 · 시험
13
+ 26파일(새 못 셋 포함). 내가 **못 셋을 깨서** 그것이 참으로 그 결함을 잡는지 확인했다.
14
+
15
+ ### 때를 틀리게 적던 것
16
+
17
+ - **훈련 시간이 전날로 기록됐다**(`useTrainingSessionLog`). 끝 시각을 *처음 보인 때 + 누계*
18
+ 로 지어서, 23:50 에 1분 쓰고 자정 넘어 00:10 에 1분 더 쓰면 **둘째 줄도 23:51~23:52** 로
19
+ 갔다. 날짜별 집계가 이 시각을 쓰면 **잘못된 날**에 들어간다. 이제 **실제로 떠난 때**를
20
+ 끝으로 두고 거기서 안 보낸 몫만큼 거슬러 올라간다.
21
+ - **자료가 늦게 오면 빈 세트가 캐시로 굳었다**(`getTrainingData`). 자료 도착 뒤
22
+ `_cachedSelection` 을 비운다.
23
+
24
+ ### 캐시가 틀린 것을 영구히 쥐던 것
25
+
26
+ - **강제 재확인이 안 들었다**(`imageConfig`). `force: true` 여도 저장된 404 를 먼저 읽어,
27
+ 한 번 없던 이미지가 나중에 올라와도 갱신되지 않았다. 늦게 온 옛 응답이 새 값을 덮지
28
+ 않게도 했다(`bulkSetImageExistence`·`clearImageExistenceCache` 포함).
29
+ - **권한 오류(403)를 "이미지 없음" 으로 담았다**(`imageConfig`·`ttsConfig`). 이제 **2xx 와
30
+ 404·410 만** 담는다. ⚠️ **소비자 확인이 필요하다** — 이미지·소리 host 가 없는 파일에
31
+ 404 가 아니라 403 을 주면, 담기지 않아 매번 다시 묻는다(틀린 값을 영구히 쥐는 것보다는
32
+ 낫지만 요청이 는다).
33
+ - `localStorage` 에 든 값이 참거짓이 아니면 걸러 담는다. 짝 색인(`wordPairIndex`)도 꼴을
34
+ 검사하고 아니면 버린다.
35
+
36
+ ### 늦게 온 답이 새 화면을 덮던 것 (여섯 자리)
37
+
38
+ `useDailyTrainingSelection`(사용자·날짜가 바뀌면 옛 선택을 안 보인다) ·
39
+ `useWordImage`(주소가 바뀐 첫 그림에 옛 실패를 안 쓴다) · `useIcon`(prop 바뀐 첫 칸에
40
+ 옛 파일 상태를 숨긴다) · `usePasswordChange`(닫은 폼의 늦은 답) ·
41
+ `useCacheManagement`(`storage.estimate`) · `TrainingPagePopup`(로드 중 바꾼 소음 설정을
42
+ 창을 닫아도 저장값 위에 병합해 남긴다).
43
+
44
+ ### 안 끝나던 것 · 새던 것
45
+
46
+ - **폴링 타이머가 남았다**(`useDailyTrainingSelection`). 첫 조회가 동기로 끝나면
47
+ `apply()` 가 `stop()` 을 부르는데 그때 `timer` 가 아직 `undefined` 였고, 그 뒤 만든
48
+ 250ms 타이머가 화면을 떠날 때까지 깨어 있었다. 타이머를 **먼저** 만든다.
49
+ - **뜻 조회의 1분 유예가 같은 화면에서는 끝나지 않았다**(`useWordMeanings`). 망이
50
+ 돌아와도 화면을 다시 열기 전까지 재조회가 없었다. 유예 만료 타이머를 둔다.
51
+ - `speak` 의 `onEnd` 가 **두 번** 불릴 수 있었다(end + error). 한 번만 불린다.
52
+
53
+ ### 새어 나가던 초점 · 깨지던 쪽 셈
54
+
55
+ - **숨은 단추를 Tab 대상으로 셌다**(`useFocusTrap`). `aria-hidden` 만 보고 `hidden`·
56
+ `inert`·`display:none`·`visibility:hidden` 은 안 봐서 초점이 **창 밖으로** 빠졌다.
57
+ - **쪽크기에 목록 밖 값이 오면 표가 비고 총 쪽수가 `NaN`** 이었다(`useTablePaging`).
58
+ 허용된 값만 받고, 소수·음수 쪽은 정수로 맞춘다(`useListControls`·`useVisitAllPanel` 도).
59
+ - 이어 붙인 열쇠(`join('|')`)를 **배열 직렬화**로 바꿨다 — 값 자체에 `|` 가 있으면 서로
60
+ 다른 조합이 같은 열쇠가 됐다(`useWordMeanings`·`useListControls`·`useSoundCompassExam`).
61
+
62
+ ### 속에 넣는 SVG 를 DOMPurify 로 씻는다
63
+
64
+ `stripActiveSvg` 의 글자 치환이 **따옴표 없는 `href=javascript:…`** 와 엔티티·
65
+ `foreignObject` 를 놓쳤고, `BrandLogo` 가 그 결과를 문서에 넣었다. 저장소 안 호출부는
66
+ 로컬 로고지만 **공개 컴포넌트에 믿을 수 없는 주소를 넘기면** 위험하다. 이 저장소가
67
+ `useIcon` 에서 이미 쓰던 길(DOMPurify)로 옮겼다 — 꾸러미도 몸집도 안 늘어난다
68
+ (`dompurify` 는 처음부터 `dependencies` 였고 `useIcon` 이 이미 묶음에 넣고 있었다).
69
+ 로고 안의 그라데이션 참조(`url(#id)`)는 지키고 외부 자원은 걷는다.
70
+
71
+ ⚠️ `stripActiveSvg` 는 **서버에서 `''` 를 돌려준다**(DOM 이 없다). `BrandLogo` 는 그
72
+ 자리에서 `<img>` 로 물러서므로 화면은 안 바뀐다.
73
+
74
+ ## 0.343.0 — 로고 일을 닫는다
75
+
76
+ 사장님이 *"로고 심볼 수정할 일 없다"* 고 하셔서, 내보내기를 고쳐 달라던 요청
77
+ (`LOGO-EXPORT-REQUEST.md`)을 **거뒀다.** 지금 셈은 이렇다.
78
+
79
+ ```
80
+ id 가 파일 이름과 같은 파일 41 / 41 (면제 0줄)
81
+ 없앤 말(white·black·textWhite)이 속에 남은 것 0
82
+ 오른쪽 여백이 20 인 로고 28 / 28
83
+ 빈 파일 0
84
+ ```
85
+
86
+ ### 글을 못 옆으로 옮겼다
87
+
88
+ 요청서에 적혀 있던 것 — **`<svg id>` 는 일러스트레이터 아트보드 이름이고, 아트보드는 아직
89
+ `_kor`/`_eng` 라서 다시 내보내면 돌아온다** — 를 `test/logoInternalIds.test.ts` 머리글로
90
+ 옮겼다. 뿌리 문서에 두면 그때 아무도 안 읽는다. **못이 우는 자리에 적혀 있어야** 읽는다.
91
+
92
+ 그 글에 길 둘을 적었다: 아트보드 이름을 고치는 것(참 고침, `Export for Screens` 로 파일
93
+ 이름과 id 가 함께 나온다)과 뿌리 id 한 자리만 고치는 것. 그리고 **표에 줄을 적어 면제하지는
94
+ 않는다**고 적었다 — 면제는 못 고치는 동안만 쓰는 것이고 이것은 한 자리 고치면 끝난다.
95
+
96
+ ### 로고 쪽에 선 못 넷
97
+
98
+ | 못 | 세는 것 |
99
+ |---|---|
100
+ | `logoFileShape` | 이름 규칙 · 그릴 마디 · 짝 칸 · 세로 · CSS 비 |
101
+ | `logoInternalIds` | 뿌리 id ↔ 파일 이름 · 되부름의 꼴 · `<style>` 없음 |
102
+ | `logoRightMargin` | 오른쪽 여백 20 (참 경계를 재서) |
103
+ | `ihabOutlinePath` | PassCard 물결이 쓰는 IHAB 윤곽 |
104
+
10
105
  ## 0.342.0 — 셈이 안 한 일을 했다고 적지 않는다
11
106
 
12
- **소비자가 받는 알맹이는 0.341.0 과 같다.** `dist` 는 한 바이트도 안 바뀌었고, 달라진 것은
13
- `scripts/` 한 줄과 이 글이다(`files` 가 `CHANGELOG.md` 와 `dist` 뿐이라 `scripts/` 는 안 실린다).
107
+ **소비자가 받는 알맹이는 0.341.0 과 같다.** 꾸러미를 받아 견줬더니 `dist` 여덟 파일이
108
+ 다른데 **차이가 판 이름(`0.341.0` → `0.342.0`)뿐**이었다 — 판 이름을 같게 놓고 해시로 세어
109
+ 확인했다. `dist/logo` 41개는 0개 다름. 달라진 것은 `scripts/` 한 줄과 이 글이다
110
+ (`files` 가 `CHANGELOG.md` 와 `dist` 뿐이라 `scripts/` 는 안 실린다).
14
111
  **올릴 일이 아닌데 올린 판**이라 적어 둔다 — 사장님 지시로 냈다.
15
112
 
113
+ > 처음 이 자리에 *"`dist` 는 한 바이트도 안 바뀌었다"* 고 적었다. **틀렸다** — 판 이름이
114
+ > 묶음 여섯 곳에 박히는 것을 안 세고 적었다. 뜻은 같지만 적은 글자가 거짓이었다.
115
+ > 바로 그 아래에서 *"셈이 제 일에 대해 적는 말도 참이어야 한다"* 고 쓰면서 그랬다.
116
+
16
117
  사장님이 `node scripts/logo-right-margin.mjs --apply` 를 직접 돌리셨다. 어긋난 것이 **0 인데
17
118
  끝줄이 `(고쳤다)`** 라고 적었다. 아무 파일도 안 썼는데 했다고 적은 것이다.
18
119