@ihabdevteam/core 0.347.0 → 0.349.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,134 @@ All notable changes to this project will be documented in this file.
7
7
  > 적은 글이라, 지금 이름으로 고쳐 놓으면 그 시절에 그 이름으로 받은 사람이
8
8
  > 제 이야기를 못 찾는다.
9
9
 
10
+ ## 0.349.0 — 사전에서 죽은 열쇠 277개를 걷었다
11
+
12
+ ### 사전에서 죽은 열쇠 277개를 걷었다 — 첫 화면 조각에서 약 16KB
13
+
14
+ 말귀 청(2026-10-20). 코어 `ko.json` 1,010 열쇠 가운데 **앱도 코어도 안 부르는** 것들이 첫 화면
15
+ 조각(`index-*.js`, gzip 100KB)에 그대로 실리고 있었다. 말귀가 재어 289개를 짚고 목록을
16
+ `docs/CORE_DEAD_I18N_KEYS_2026-10-20.md` 로 넘기며 *"걷기 전에 코어 쪽에서 한 번 더 보라"* 고
17
+ 적어 두었다. 봤더니 **열하나가 살아 있었다.**
18
+
19
+ | | 전 | 후 |
20
+ |---|---|---|
21
+ | `ko.json` | 1,010 | **733** (277 지움) |
22
+ | `en.json` | 1,028 | **749** |
23
+
24
+ 갈래가 통째로 사라진 것: `game` · `landing` · `login` · `help` · `company` · `inquiry` ·
25
+ `homework` · `trainingSettings` · `accessLinkManager` · `searchField` · `myWordTraining` ·
26
+ `trainingPlanRun` · `trainingSetPage` · `wordTrainingPreview`.
27
+
28
+ #### 살려 둔 열하나 — 말귀 잼이 못 보는 세 자리
29
+
30
+ 그쪽 잼은 코어 `dist/**/*.js` 를 봤는데 거기 **놀이터도 시험도 없고**, 앱 쪽은 `deadI18nKeys`
31
+ 가 얼린 목록(= 앱 **화면**이 안 부르는 것)이라 **앱 시험**이 빠진다.
32
+
33
+ | 열쇠 | 어디서 쓰나 |
34
+ |---|---|
35
+ | `training.result.elapsed` | 놀이터 `BarChartPage:229·232` |
36
+ | `trainingStatus.weekly.title` · `.daily` | 놀이터 `BarChartPage:165·168·181·194` |
37
+ | `trainingStatus.homework.totalRate` | 놀이터 `RingChartPage:122·123` |
38
+ | `training.audioStatus.synthesizing` | 코어 시험 `audioStatusSynthesizing:33` |
39
+ | `trainingMiss.runs` · `.skippedOnly` | 코어 시험 `enPluralForms:48·53·54` |
40
+ | `customers.visitHistory.registerTitle` · `.popupTitle` · `customers.schedule.registerTitle` | **말귀 시험** `customerPopupTitleSpacing` |
41
+ | `wordPairs.confirmMessage` | 코어 시험 `enPluralForms` 의 `EXCLUDED` 목록 |
42
+
43
+ 말귀 시험 셋이 특히 그렇다 — 그쪽 `test/i18nResources` 가 **코어 사전 위에 앱 사전을 얹어**
44
+ 주고, 이 셋은 **코어에만 있다.** 그 파일 머리말이 바로 이 날을 적어 두고 있었다:
45
+ *"코어가 옛 사본을 걷는 날 한꺼번에 빨개진다."*
46
+
47
+ #### 영어 복수 짝이 목록에 없었다 — 찾아낸 것 여덟, 지운 것 **넷**
48
+
49
+ 그쪽 목록은 `ko.json` 열쇠로 만들어져 **`_one`/`_other` 가 빠져 있다**(en 이 18개 많은 까닭).
50
+ 열쇠만 지우면 그 짝이 en 에 남는다. 목록 열쇠의 짝으로 **여덟**을 찾아 그중 **넷**을 걷었다 —
51
+ 나머지 넷은 위에서 살려 둔 열쇠의 짝이라 함께 남는다.
52
+
53
+ ```
54
+ 지웠다 accessLinkManager.uses_one · _other · trainingStatus.time.countLabel_one · _other
55
+ 남겼다 trainingMiss.runs_one · _other · trainingMiss.skippedOnly_one · _other
56
+ ```
57
+
58
+ **찾아낸 수와 지운 수를 같은 칸에 적지 않는다** — 말귀에 처음 알릴 때 여덟을 지운 수인 양
59
+ 적었다가 바로잡았다. 빈 마디도 걷었다.
60
+
61
+ ko 277 · en 279(복수 짝 넷 포함)를 지웠다. 둘의 차는 ko 에만 있던 열쇠 둘이다.
62
+
63
+ #### 소비자는 넷이다 — 말귀가 잰 둘이 다가 아니다
64
+
65
+ `kscan` · `sound-localization-system` · `ihab_offcial_web/admin` 도 코어를 쓴다. 셋 다 `t()` 를
66
+ **직접 안 부르고**(코어 컴포넌트가 제 안에서 부른다) 0건이 걸렸다. 앞 둘은 아직 `^0.211.0` 이라
67
+ 이 판이 닿지도 않는다. **안 재고 0건인 것과 재서 0건인 것은 다르다.**
68
+
69
+ #### 내 그물이 세 번 성겼다 — 셋째는 **관문이** 잡았다
70
+
71
+ ① 처음엔 **289 중 289가 "살아 있다"** 로 나왔다 — 말귀의 **얼린 목록 자체**
72
+ (`deadI18nKeys.test.ts`, 276건)를 쓰임으로 세고 있었고, **kscan 을 통째로 건너뛰었다**(소스가
73
+ `src/` 가 아니라 Next.js 꼴이라 `src` 만 짚은 훑기에 안 걸렸다).
74
+
75
+ ② 고쳐서 31로 줄였더니 다섯이 **더 긴 열쇠의 앞머리**였다 — `store.import` 가
76
+ `store.importAria` 에, `usage.pending.title` 이 `usage.pending.titleSpeechear` 에.
77
+ **경계 없는 찾기는 짧은 열쇠를 전부 살려 낸다.**
78
+
79
+ ③ 그래서 앞뒤로 `(?<![A-Za-z0-9_.])…(?![A-Za-z0-9_.])` 를 둘렀더니 이번엔
80
+ `training.audioStatus.synthesizing` 를 **놓쳤다.** 그 시험은 열쇠를 글자가 아니라 **속성으로**
81
+ 탄다 — `(d as …).training.audioStatus.synthesizing`, 앞 글자가 `.` 이다. 지우고 관문을 돌려
82
+ **빨강으로 알았다.**
83
+
84
+ **앞뒤 경계는 다르다.** 뒤는 `.` 을 막아야 하고(긴 열쇠에 안 걸리게), 앞은 막으면 안 된다
85
+ (속성으로 타는 쓰임을 놓친다). 앞에 긴 길이 붙어 헛걸리는 쪽은 **열쇠를 살려 두는** 쪽이라
86
+ 지우기 판단에서는 안전한 틀림이다.
87
+
88
+ ## 0.348.0 — 다시 듣기가 같은 소리를 또 받던 것 (311, 급함)
89
+
90
+ **사장님이 폰에서 숙제 단어훈련을 하시다 신고하셨다** — *"소리가 끊기고, 재생바와 사운드
91
+ 현황이 맞지 않고, 소스를 가져오지 못했다는 말도 나온다."*
92
+
93
+ 말귀가 폰 폭(375px)에서 `HTMLMediaElement` 의 `src`·`load()`·`play()` 를 가로채 부른 자리까지
94
+ 적었다. **한 낱말(0.77초)을 한 번 듣는 동안**:
95
+
96
+ ```
97
+ set src (id 1) measureAudioDuration ← 길이 재려고 만든 <audio>
98
+ set src (id 2) measureAudioDuration ← 같은 URL 을 다른 길에서 또
99
+ set src (id 3) loadAndPlay ← 실제로 틀 <audio>
100
+ set src (id 3) continuePlay ← 다시 듣기에서 **같은 URL 을 또**
101
+ ```
102
+
103
+ `load()` 는 **새 요청**이다. 로컬에서 1초인 것이 느린 망에서는 그만큼 **침묵**이 되고(끊김),
104
+ 그중 **하나만 실패해도** *"소스를 가져오지 못했다"* 가 된다. **되풀이마다 하나씩 더** 붙었다.
105
+
106
+ ### 고친 것 — 들고 있는 소리는 다시 안 받는다
107
+
108
+ `loadSound` 가 이미 그 주소를 들고 있고 길이까지 알면(`readyState >= HAVE_METADATA`)
109
+ `currentTime = 0` 만 하고 돌아온다. 새 규칙 `needsReload`(`audioPlaybackRules`):
110
+
111
+ - **주소는 풀어서 견준다** — 부르는 쪽은 상대 주소를 줄 수 있고 `currentSrc` 는 늘 절대
112
+ 주소라, 글자로 견주면 **같은 파일을 늘 다르다고 본다**(그러면 아무것도 안 아낀다).
113
+ - **서명 주소의 토큰이 다르면 받는다** — 그때는 참으로 다른 주소다(만료된 것으로 틀면 안 된다).
114
+ - **아직 안 실렸으면 받는다** — 틀 것이 없다.
115
+
116
+ 네 가지로 깨 보고 넷 다 붉어졌다.
117
+
118
+ ### 아직 안 한 둘 — 까닭을 적어 둔다
119
+
120
+ - **길이를 틀 그 요소에서 재기.** `waitForCanPlay` 는 `canplay`·`error`·시간초과를 **모두
121
+ resolve** 한다(거절하지 않는다). 지금 길은 `measureAudioDuration(..., {rejectOnError: true})`
122
+ 의 **거절**로 오류를 바깥 `catch` 에 넘기는데, 그것으로 바꾸면 **오류가 조용히 삼켜진다.**
123
+ 같은 파일을 두 번 덜 받는 값이 크지만, 오류 전달을 먼저 지어야 한다.
124
+ - **받는 동안 막대 안 움직이기.** 뜸 구간은 `Date.now()` 로 밀리는데, 그 구간의 생애
125
+ (`sequencer.positionRef`)를 건드려야 한다. 급한 것을 먼저 냈다.
126
+
127
+ ### 세우며 겪은 것 — 흉내가 빈약해서 난 거짓 빨강 95개
128
+
129
+ 처음에 `needsReload` 를 `audioWaits.ts` 에 넣었더니 **시험 95개가 빨개졌다.** 그 모듈은
130
+ **열두 시험이 공장 꼴로 흉내** 낸다 — 공장은 자기가 쓰는 이름만 내보내므로 이름을 하나
131
+ 더하면 그 열둘에서 `undefined` 가 되어 던진다. **코드는 맞았고 흉내가 빈약했다.**
132
+
133
+ 가리는 데 품이 들었다: `needsReload` 를 **늘 참**으로 바꿔도(= 고치기 전과 같은 길) 그대로
134
+ 빨개서 한참 딴 데를 봤다. 흉내가 **들여오는 때**에 깨지니 함수 속을 어떻게 바꿔도 소용이
135
+ 없었던 것이다. 순수 규칙을 **흉내 내는 시험이 0 곳인** `audioPlaybackRules.ts` 로 옮겼다 —
136
+ 그러면 다음에 규칙을 더해도 그 열둘이 안 깨진다.
137
+
10
138
  ## 0.347.0 — `autoFocus` 자식이 있는 창을 닫으면 초점을 잃던 것 (310)
11
139
 
12
140
  창은 열 때 *"지금 초점이 어디였나"* 를 적어 두고 닫을 때 그리로 돌려준다. 그 적는 줄이