@ihabdevteam/core 0.323.0 → 0.324.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 +40 -0
- package/dist/components.cjs.js +3 -3
- package/dist/hooks.cjs.js +3 -3
- package/dist/i18n.cjs.js +3 -3
- package/dist/ihabdevteam-core.cjs.js +184 -184
- package/dist/ihabdevteam-core.d.ts +2 -2
- package/dist/packages/core/src/i18n/locales/en.json +1 -0
- package/dist/packages/core/src/i18n/locales/ko.json +1 -0
- package/dist/packages/core/src/utils/phonemePairSearch.js +13 -5
- package/dist/packages/core/src/utils/phonemePairSearchTypes.d.ts +2 -0
- package/dist/packages/core/src/utils/wordAttributeFilterCodes.d.ts +1 -1
- package/dist/packages/core/src/utils/wordAttributeFilterCodes.js +23 -3
- package/dist/packages/core/src/version.d.ts +1 -1
- package/dist/packages/core/src/version.js +1 -1
- package/dist/utils.cjs.js +3 -3
- package/package.json +1 -1
|
@@ -1678,7 +1678,7 @@ export declare function copyText(text: string): Promise<boolean>;
|
|
|
1678
1678
|
*
|
|
1679
1679
|
* 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
|
|
1680
1680
|
*/
|
|
1681
|
-
export declare const CORE_VERSION = "0.
|
|
1681
|
+
export declare const CORE_VERSION = "0.324.0";
|
|
1682
1682
|
|
|
1683
1683
|
/** @public */
|
|
1684
1684
|
declare const coreDefault: Record<string, unknown>;
|
|
@@ -10700,7 +10700,7 @@ export declare interface WordAttributeFilterKeys {
|
|
|
10700
10700
|
}
|
|
10701
10701
|
|
|
10702
10702
|
/** @public 공용 속성 필터 섹션 코드 */
|
|
10703
|
-
export declare type WordAttributeSectionCode = 'grade' | 'syllables' | 'pos' | 'wordType';
|
|
10703
|
+
export declare type WordAttributeSectionCode = 'grade' | 'syllables' | 'pos' | 'wordType' | 'field';
|
|
10704
10704
|
|
|
10705
10705
|
/** 정답 단어 구성 선택 상태 (정답 단어에만 적용 — 오답은 대립 관계로 결정) */
|
|
10706
10706
|
export declare interface WordComposition {
|
|
@@ -127,6 +127,7 @@ const DEFAULT_PAIR_FILTER_KEYS = {
|
|
|
127
127
|
syllable5plus: '5음절 이상',
|
|
128
128
|
partOfSpeech: '품사',
|
|
129
129
|
wordType: '유형',
|
|
130
|
+
field: '의미범주',
|
|
130
131
|
posMap: POS_GROUP_MAP_KO,
|
|
131
132
|
typeMap: WORD_TYPE_MAP_KO,
|
|
132
133
|
};
|
|
@@ -135,13 +136,14 @@ function collect(filterSelected, keys) {
|
|
|
135
136
|
const hit = collected.get(filterSelected);
|
|
136
137
|
if (hit && hit.keys === keys)
|
|
137
138
|
return hit.value;
|
|
138
|
-
const value = { grades: [], syls: [], poses: [], types: [] };
|
|
139
|
-
const bySection = { grade: value.grades, syllables: value.syls, pos: value.poses, wordType: value.types };
|
|
139
|
+
const value = { grades: [], syls: [], poses: [], types: [], fields: [] };
|
|
140
|
+
const bySection = { grade: value.grades, syllables: value.syls, pos: value.poses, wordType: value.types, field: value.fields };
|
|
140
141
|
for (const [label, raw] of Object.entries(filterSelected ?? {})) {
|
|
141
142
|
/* 섹션은 넘긴 keys 의 라벨이면 그것, 아니면 어느 언어·옛 라벨·코드든 읽는다(wordAttributeSectionOf) */
|
|
142
143
|
const s = label === keys.difficulty ? 'grade' : label === keys.syllables ? 'syllables'
|
|
143
144
|
: label === keys.partOfSpeech ? 'pos' : label === keys.wordType ? 'wordType'
|
|
144
|
-
:
|
|
145
|
+
: label === keys.field ? 'field'
|
|
146
|
+
: wordAttributeSectionOf(label);
|
|
145
147
|
if (!s)
|
|
146
148
|
continue;
|
|
147
149
|
for (const v of Array.isArray(raw) ? raw : typeof raw === 'string' ? [raw] : [])
|
|
@@ -193,8 +195,14 @@ export function applyFilters(filterSelected, words, keys = DEFAULT_PAIR_FILTER_K
|
|
|
193
195
|
return words.filter(entry => {
|
|
194
196
|
if (!matchesFilters({ grade: entry.grade, syllables: [...entry.word].length, pos: entry.pos, wordType: entry.wordType }, filterSelected, keys))
|
|
195
197
|
return false;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
/* **의미범주도 다른 넷과 같은 길로 읽는다**(사장님 지시 2026-10-14, 말귀 실측으로 다리는
|
|
199
|
+
필요 없음이 확인됐다 — 앱 소스 0건·저장 구성 416줄 0건).
|
|
200
|
+
|
|
201
|
+
전에는 `filterSelected['의미범주']` 로 **그 다섯 글자만** 찾았다. 다른 절은 어느 언어
|
|
202
|
+
라벨이든 읽는데 이 하나만 안 그랬고, 영어 라벨로 부르면 **이 필터만 조용히 안 걸렸다**
|
|
203
|
+
(에러도 없다). 같은 꼴을 등급·음절에서 이미 겪어 고쳤던 자리다. */
|
|
204
|
+
const { fields } = collect(filterSelected, keys);
|
|
205
|
+
if (fields.length) {
|
|
198
206
|
const normalized = (entry.field ?? '').replace(/전문\(|\)/g, '');
|
|
199
207
|
if (!fields.some(f => normalized.includes(f)))
|
|
200
208
|
return false;
|
|
@@ -25,6 +25,8 @@ export interface PairFilterKeys {
|
|
|
25
25
|
syllable5plus: string;
|
|
26
26
|
partOfSpeech: string;
|
|
27
27
|
wordType: string;
|
|
28
|
+
/** 의미범주 절의 이름표. **안 줘도 된다** — 안 주면 어느 언어 라벨이든 사전으로 읽는다(0.324.0). */
|
|
29
|
+
field?: string;
|
|
28
30
|
posMap: Record<string, string[]>;
|
|
29
31
|
typeMap: Record<string, string>;
|
|
30
32
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @public 공용 속성 필터 섹션 코드 */
|
|
2
|
-
export type WordAttributeSectionCode = 'grade' | 'syllables' | 'pos' | 'wordType';
|
|
2
|
+
export type WordAttributeSectionCode = 'grade' | 'syllables' | 'pos' | 'wordType' | 'field';
|
|
3
3
|
/**
|
|
4
4
|
* **등급이 빈 단어를 가리키는 코드** — `'none'`((205), 사장님 지시 2026-10-12).
|
|
5
5
|
*
|
|
@@ -11,6 +11,18 @@
|
|
|
11
11
|
* (useWordTrainingFilter 의 POS_CODES·toAttrCodes 와 같은 코드다.)
|
|
12
12
|
*/
|
|
13
13
|
import i18n from '../i18n';
|
|
14
|
+
/**
|
|
15
|
+
* **값이 코드가 아닌 절** — 지금은 `field`(의미범주) 하나다.
|
|
16
|
+
*
|
|
17
|
+
* 다른 넷은 값도 코드다(`'1'`·`'5+'`·`'noun'`·`'sino'`). 이 절의 값은 **사전이 들고 있는
|
|
18
|
+
* 분야 글자 자신**(`의학`·`법률`…)이라 미리 셀 수가 없고, 맞출 때도 같은지가 아니라
|
|
19
|
+
* **들어 있는지**로 본다(`entry.field` 가 `전문(의학)` 꼴이다).
|
|
20
|
+
*
|
|
21
|
+
* 그래서 값은 **그대로 지나간다** — 코드로 바꾸지도, 라벨로 되돌리지도 않는다. 이것을 안
|
|
22
|
+
* 가르면 저장할 때 `wordAttributeValueCodeOf` 가 `null` 을 내어 **고른 값이 통째로
|
|
23
|
+
* 버려지고**, 되읽을 때도 사전에 없어 사라진다. 둘 다 조용히 일어난다.
|
|
24
|
+
*/
|
|
25
|
+
const FREE_VALUE_SECTIONS = new Set(['field']);
|
|
14
26
|
/**
|
|
15
27
|
* **등급이 빈 단어를 가리키는 코드** — `'none'`((205), 사장님 지시 2026-10-12).
|
|
16
28
|
*
|
|
@@ -59,13 +71,14 @@ export function matchesGradeCodes(codes, grade) {
|
|
|
59
71
|
return set.has(GRADE_NONE);
|
|
60
72
|
return set.has(String(grade));
|
|
61
73
|
}
|
|
62
|
-
const sectionCodes = ['grade', 'syllables', 'pos', 'wordType'];
|
|
74
|
+
const sectionCodes = ['grade', 'syllables', 'pos', 'wordType', 'field'];
|
|
63
75
|
/** 등급 코드 — `'none'` 은 **등급이 빈 단어**다(값이 아니라 **빔**이다. GRADE_NONE 주석을 볼 것) */
|
|
64
76
|
const gradeValues = ['1', '2', '3', '4', 'none'];
|
|
65
77
|
const syllableValues = ['1', '2', '3', '4', '5+'];
|
|
66
78
|
const posValues = ['noun', 'verb', 'modifier'];
|
|
67
79
|
const wordTypeValues = ['native', 'sino', 'foreign', 'mixed'];
|
|
68
|
-
|
|
80
|
+
/* `field` 는 값이 자유라 셀 목록이 없다 — `FREE_VALUE_SECTIONS` 를 볼 것 */
|
|
81
|
+
const valuesBySection = { grade: gradeValues, syllables: syllableValues, pos: posValues, wordType: wordTypeValues, field: [] };
|
|
69
82
|
/** 품사 코드 → 사전 품사 약자(단어의 pos 에 들어 있는지 본다) · 어종 코드 → 사전 어종 값 */
|
|
70
83
|
export const POS_CODE_TARGETS = { noun: ['명', '수'], verb: ['동', '형'], modifier: ['부', '관'] };
|
|
71
84
|
export const WORD_TYPE_CODE_VALUES = { native: '고유', sino: '한자', foreign: '외래', mixed: '혼종' };
|
|
@@ -91,6 +104,7 @@ function dictFor(lng) {
|
|
|
91
104
|
syllables: t('wordSearch.filter.syllables', '음절 수'),
|
|
92
105
|
pos: t('wordSearch.filter.partOfSpeech', '품사'),
|
|
93
106
|
wordType: t('wordSearch.filter.wordType', '유형'),
|
|
107
|
+
field: t('wordSearch.filter.field', '의미범주'),
|
|
94
108
|
},
|
|
95
109
|
value: {
|
|
96
110
|
grade: {
|
|
@@ -113,6 +127,8 @@ function dictFor(lng) {
|
|
|
113
127
|
foreign: t('wordSearch.filter.type.foreign', '외래어'),
|
|
114
128
|
mixed: t('wordSearch.filter.type.mixed', '혼종어'),
|
|
115
129
|
},
|
|
130
|
+
/* 값이 자유로운 절 — 라벨이 곧 값이라 표가 비어 있다(`wordAttributeValueLabelOf` 가 코드를 그대로 돌려준다) */
|
|
131
|
+
field: {},
|
|
116
132
|
},
|
|
117
133
|
};
|
|
118
134
|
dictCache.set(lng, d);
|
|
@@ -136,6 +152,9 @@ export function wordAttributeSectionOf(label) {
|
|
|
136
152
|
}
|
|
137
153
|
/** 한 섹션의 값(코드·어느 언어 라벨·옛 라벨) → 값 코드. 못 읽으면 null. */
|
|
138
154
|
export function wordAttributeValueCodeOf(section, value) {
|
|
155
|
+
/* 값이 자유로운 절은 **그대로 지나간다** — 코드가 따로 없다(`FREE_VALUE_SECTIONS`) */
|
|
156
|
+
if (FREE_VALUE_SECTIONS.has(section))
|
|
157
|
+
return value;
|
|
139
158
|
if (valuesBySection[section].includes(value))
|
|
140
159
|
return value;
|
|
141
160
|
for (const lng of languages()) {
|
|
@@ -191,7 +210,8 @@ export function wordAttributeFilterFromCodes(codes, lng = i18n.language) {
|
|
|
191
210
|
const d = dictFor(lng || 'ko');
|
|
192
211
|
const out = {};
|
|
193
212
|
for (const s of sectionCodes) {
|
|
194
|
-
|
|
213
|
+
/* 자유 절은 값이 곧 라벨이다 — 사전에 없다고 버리면 저장했다 되읽을 때 사라진다 */
|
|
214
|
+
const labels = (codes?.[s] ?? []).map((c) => d.value[s][c] ?? (FREE_VALUE_SECTIONS.has(s) ? c : undefined)).filter((x) => !!x);
|
|
195
215
|
if (labels.length)
|
|
196
216
|
out[d.section[s]] = labels;
|
|
197
217
|
}
|