yomitan-core 0.1.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/README.md +485 -0
- package/dist/anki-connect-BQyCGW3O.cjs +513 -0
- package/dist/anki-connect-BQyCGW3O.cjs.map +1 -0
- package/dist/anki-connect-CPPuhyiQ.js +6 -0
- package/dist/anki-connect-DbrQHphS.js +495 -0
- package/dist/anki-connect-DbrQHphS.js.map +1 -0
- package/dist/anki-connect-DcheJrp-.cjs +6 -0
- package/dist/anki.cjs +1758 -0
- package/dist/anki.cjs.map +1 -0
- package/dist/anki.d.cts +751 -0
- package/dist/anki.d.cts.map +1 -0
- package/dist/anki.d.ts +751 -0
- package/dist/anki.d.ts.map +1 -0
- package/dist/anki.js +1751 -0
- package/dist/anki.js.map +1 -0
- package/dist/audio-D9DvYyB7.d.cts +48 -0
- package/dist/audio-D9DvYyB7.d.cts.map +1 -0
- package/dist/audio-DQulUkDM.d.ts +48 -0
- package/dist/audio-DQulUkDM.d.ts.map +1 -0
- package/dist/audio-url-generator-BXvQaqUi.cjs +4 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs +414 -0
- package/dist/audio-url-generator-Dy2hb2Mm.cjs.map +1 -0
- package/dist/audio-url-generator-Qi0rfzHz.js +4 -0
- package/dist/audio-url-generator-pFQAB5Nb.js +390 -0
- package/dist/audio-url-generator-pFQAB5Nb.js.map +1 -0
- package/dist/audio.cjs +7 -0
- package/dist/audio.d.cts +86 -0
- package/dist/audio.d.cts.map +1 -0
- package/dist/audio.d.ts +86 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +4 -0
- package/dist/batch-processor-BR-gB3H3.js +84 -0
- package/dist/batch-processor-BR-gB3H3.js.map +1 -0
- package/dist/batch-processor-CSF1acTw.cjs +3 -0
- package/dist/batch-processor-DFqM_L-_.cjs +91 -0
- package/dist/batch-processor-DFqM_L-_.cjs.map +1 -0
- package/dist/batch-processor-Quo9jUyf.js +3 -0
- package/dist/chunk-BCwAaXi7.cjs +31 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs +167 -0
- package/dist/cjk-util-Dp0ZU0sh.cjs.map +1 -0
- package/dist/cjk-util-DubXBGDG.js +94 -0
- package/dist/cjk-util-DubXBGDG.js.map +1 -0
- package/dist/core-BUpclilG.d.cts +102 -0
- package/dist/core-BUpclilG.d.cts.map +1 -0
- package/dist/core-DFUj5GtA.d.ts +102 -0
- package/dist/core-DFUj5GtA.d.ts.map +1 -0
- package/dist/database.cjs +7 -0
- package/dist/database.d.cts +4 -0
- package/dist/database.d.ts +4 -0
- package/dist/database.js +5 -0
- package/dist/dictionary-D7l-qFt1.d.cts +316 -0
- package/dist/dictionary-D7l-qFt1.d.cts.map +1 -0
- package/dist/dictionary-_vzfBLWi.d.ts +316 -0
- package/dist/dictionary-_vzfBLWi.d.ts.map +1 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs +378 -0
- package/dist/dictionary-data-util-CHnRdYZ9.cjs.map +1 -0
- package/dist/dictionary-data-util-CfOLfEDE.js +323 -0
- package/dist/dictionary-data-util-CfOLfEDE.js.map +1 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts +58 -0
- package/dist/dictionary-database-BDC2f9zc.d.ts.map +1 -0
- package/dist/dictionary-database-CU4TsvCC.js +393 -0
- package/dist/dictionary-database-CU4TsvCC.js.map +1 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts +58 -0
- package/dist/dictionary-database-DsOi04Sg.d.cts.map +1 -0
- package/dist/dictionary-database-lvFvftnO.cjs +412 -0
- package/dist/dictionary-database-lvFvftnO.cjs.map +1 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts +237 -0
- package/dist/dictionary-importer-BkQQSBhm.d.ts.map +1 -0
- package/dist/dictionary-importer-Cen1z6co.js +1821 -0
- package/dist/dictionary-importer-Cen1z6co.js.map +1 -0
- package/dist/dictionary-importer-DYmmWmcX.cjs +8 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts +237 -0
- package/dist/dictionary-importer-Da3AuTZw.d.cts.map +1 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs +1834 -0
- package/dist/dictionary-importer-Dhn75iZ4.cjs.map +1 -0
- package/dist/dictionary-importer-xWkel0h-.js +8 -0
- package/dist/dictionary-update-checker-BNE4pGTx.js +4 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs +75 -0
- package/dist/dictionary-update-checker-Byjvifd2.cjs.map +1 -0
- package/dist/dictionary-update-checker-YdpalZ41.cjs +4 -0
- package/dist/dictionary-update-checker-kKukiovj.js +69 -0
- package/dist/dictionary-update-checker-kKukiovj.js.map +1 -0
- package/dist/display-generator-BGVWiI0t.js +746 -0
- package/dist/display-generator-BGVWiI0t.js.map +1 -0
- package/dist/display-generator-BMQmG5Ov.cjs +9 -0
- package/dist/display-generator-BxZ7mBjP.js +9 -0
- package/dist/display-generator-DyP-HNzP.cjs +758 -0
- package/dist/display-generator-DyP-HNzP.cjs.map +1 -0
- package/dist/errors-BSezaJwm.cjs +35 -0
- package/dist/errors-BSezaJwm.cjs.map +1 -0
- package/dist/errors-DuuDSO5N.js +22 -0
- package/dist/errors-DuuDSO5N.js.map +1 -0
- package/dist/frequency-ranking-BXjfhhUQ.js +3 -0
- package/dist/frequency-ranking-Cx1kkIrw.cjs +3 -0
- package/dist/frequency-ranking-DEJMTMdg.js +159 -0
- package/dist/frequency-ranking-DEJMTMdg.js.map +1 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs +166 -0
- package/dist/frequency-ranking-DVYxTXN-.cjs.map +1 -0
- package/dist/furigana-5HK97CY8.js +4 -0
- package/dist/furigana-9bBI9-qe.d.ts +47 -0
- package/dist/furigana-9bBI9-qe.d.ts.map +1 -0
- package/dist/furigana-B3-0y231.js +471 -0
- package/dist/furigana-B3-0y231.js.map +1 -0
- package/dist/furigana-CjOhzvZt.d.cts +47 -0
- package/dist/furigana-CjOhzvZt.d.cts.map +1 -0
- package/dist/furigana-DpZLcues.cjs +609 -0
- package/dist/furigana-DpZLcues.cjs.map +1 -0
- package/dist/furigana-h3v2ub4-.cjs +4 -0
- package/dist/import.cjs +12 -0
- package/dist/import.d.cts +107 -0
- package/dist/import.d.cts.map +1 -0
- package/dist/import.d.ts +107 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +9 -0
- package/dist/index.cjs +275 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +211 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +238 -0
- package/dist/index.js.map +1 -0
- package/dist/json-DGd-cunA.js +17 -0
- package/dist/json-DGd-cunA.js.map +1 -0
- package/dist/json-DKWp-B7Y.cjs +30 -0
- package/dist/json-DKWp-B7Y.cjs.map +1 -0
- package/dist/language-KN_u-nTR.d.ts +104 -0
- package/dist/language-KN_u-nTR.d.ts.map +1 -0
- package/dist/language-xAbQxgXc.d.cts +104 -0
- package/dist/language-xAbQxgXc.d.cts.map +1 -0
- package/dist/language.cjs +15626 -0
- package/dist/language.cjs.map +1 -0
- package/dist/language.d.cts +959 -0
- package/dist/language.d.cts.map +1 -0
- package/dist/language.d.ts +959 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +15522 -0
- package/dist/language.js.map +1 -0
- package/dist/log-D8KtR3aP.cjs +67 -0
- package/dist/log-D8KtR3aP.cjs.map +1 -0
- package/dist/log-hgSll-dS.js +60 -0
- package/dist/log-hgSll-dS.js.map +1 -0
- package/dist/lookup.cjs +13 -0
- package/dist/lookup.d.cts +161 -0
- package/dist/lookup.d.cts.map +1 -0
- package/dist/lookup.d.ts +161 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +10 -0
- package/dist/media-loader-BABA_E4W.js +3 -0
- package/dist/media-loader-Ce9cuANS.cjs +21 -0
- package/dist/media-loader-Ce9cuANS.cjs.map +1 -0
- package/dist/media-loader-qRti-Q6h.js +14 -0
- package/dist/media-loader-qRti-Q6h.js.map +1 -0
- package/dist/media-loader-xlUGaJrx.cjs +3 -0
- package/dist/multi-language-transformer-AlxOM6b3.js +637 -0
- package/dist/multi-language-transformer-AlxOM6b3.js.map +1 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs +685 -0
- package/dist/multi-language-transformer-MdbQBBOt.cjs.map +1 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts +63 -0
- package/dist/multi-language-transformer-SEhcJXEB.d.ts.map +1 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts +63 -0
- package/dist/multi-language-transformer-Ul9mbRce.d.cts.map +1 -0
- package/dist/pronunciation-generator-BtBc4q_V.js +397 -0
- package/dist/pronunciation-generator-BtBc4q_V.js.map +1 -0
- package/dist/pronunciation-generator-CBYdXYou.js +4 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs +445 -0
- package/dist/pronunciation-generator-CFbZlf5J.cjs.map +1 -0
- package/dist/pronunciation-generator-DOz9hEuk.cjs +4 -0
- package/dist/render.cjs +2796 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +424 -0
- package/dist/render.d.cts.map +1 -0
- package/dist/render.d.ts +424 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +2777 -0
- package/dist/render.js.map +1 -0
- package/dist/sentence-parser-BPAJNzqW.js +126 -0
- package/dist/sentence-parser-BPAJNzqW.js.map +1 -0
- package/dist/sentence-parser-BVIOI64h.cjs +132 -0
- package/dist/sentence-parser-BVIOI64h.cjs.map +1 -0
- package/dist/sentence-parser-BoHO3cHn.js +5 -0
- package/dist/sentence-parser-DQVLSW0z.cjs +5 -0
- package/dist/structured-content-generator-BtOApkTW.cjs +4 -0
- package/dist/structured-content-generator-Bx62RYa8.js +4 -0
- package/dist/structured-content-generator-CLnybumI.js +276 -0
- package/dist/structured-content-generator-CLnybumI.js.map +1 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs +282 -0
- package/dist/structured-content-generator-DrwkB0-k.cjs.map +1 -0
- package/dist/text-utilities-B7PIythe.js +8 -0
- package/dist/text-utilities-B7PIythe.js.map +1 -0
- package/dist/text-utilities-Del2Ivkg.cjs +15 -0
- package/dist/text-utilities-Del2Ivkg.cjs.map +1 -0
- package/dist/translator-CRPlPzqi.cjs +1545 -0
- package/dist/translator-CRPlPzqi.cjs.map +1 -0
- package/dist/translator-CWgG5drA.js +1539 -0
- package/dist/translator-CWgG5drA.js.map +1 -0
- package/dist/translator-CaGtJvnQ.cjs +6 -0
- package/dist/translator-Cc6OGxrW.d.ts +180 -0
- package/dist/translator-Cc6OGxrW.d.ts.map +1 -0
- package/dist/translator-CcA-s-W4.d.cts +180 -0
- package/dist/translator-CcA-s-W4.d.cts.map +1 -0
- package/dist/translator-CuJOTK6l.js +6 -0
- package/dist/utilities-C-lbZaJE.cjs +52 -0
- package/dist/utilities-C-lbZaJE.cjs.map +1 -0
- package/dist/utilities-bi3EF-q5.js +33 -0
- package/dist/utilities-bi3EF-q5.js.map +1 -0
- package/package.json +102 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const require_chunk = require('./chunk-BCwAaXi7.cjs');
|
|
3
|
+
const require_log = require('./log-D8KtR3aP.cjs');
|
|
4
|
+
const require_utilities = require('./utilities-C-lbZaJE.cjs');
|
|
5
|
+
const dexie = require_chunk.__toESM(require("dexie"));
|
|
6
|
+
|
|
7
|
+
//#region src/database/schema.ts
|
|
8
|
+
var YomitanDatabase = class extends dexie.default {
|
|
9
|
+
terms;
|
|
10
|
+
termMeta;
|
|
11
|
+
kanji;
|
|
12
|
+
kanjiMeta;
|
|
13
|
+
tagMeta;
|
|
14
|
+
dictionaries;
|
|
15
|
+
media;
|
|
16
|
+
constructor(name = "dict") {
|
|
17
|
+
super(name);
|
|
18
|
+
this.version(20).stores({
|
|
19
|
+
terms: "++id, dictionary, expression, reading",
|
|
20
|
+
kanji: "++, dictionary, character",
|
|
21
|
+
tagMeta: "++, dictionary",
|
|
22
|
+
dictionaries: "++, title, version"
|
|
23
|
+
});
|
|
24
|
+
this.version(30).stores({
|
|
25
|
+
terms: "++id, dictionary, expression, reading",
|
|
26
|
+
kanji: "++, dictionary, character",
|
|
27
|
+
tagMeta: "++, dictionary, name",
|
|
28
|
+
dictionaries: "++, title, version",
|
|
29
|
+
termMeta: "++, dictionary, expression",
|
|
30
|
+
kanjiMeta: "++, dictionary, character"
|
|
31
|
+
});
|
|
32
|
+
this.version(40).stores({
|
|
33
|
+
terms: "++id, dictionary, expression, reading, sequence",
|
|
34
|
+
kanji: "++, dictionary, character",
|
|
35
|
+
tagMeta: "++, dictionary, name",
|
|
36
|
+
dictionaries: "++, title, version",
|
|
37
|
+
termMeta: "++, dictionary, expression",
|
|
38
|
+
kanjiMeta: "++, dictionary, character"
|
|
39
|
+
});
|
|
40
|
+
this.version(50).stores({
|
|
41
|
+
terms: "++id, dictionary, expression, reading, sequence, expressionReverse, readingReverse",
|
|
42
|
+
kanji: "++, dictionary, character",
|
|
43
|
+
tagMeta: "++, dictionary, name",
|
|
44
|
+
dictionaries: "++, title, version",
|
|
45
|
+
termMeta: "++, dictionary, expression",
|
|
46
|
+
kanjiMeta: "++, dictionary, character"
|
|
47
|
+
});
|
|
48
|
+
this.version(60).stores({
|
|
49
|
+
terms: "++id, dictionary, expression, reading, sequence, expressionReverse, readingReverse",
|
|
50
|
+
kanji: "++, dictionary, character",
|
|
51
|
+
tagMeta: "++, dictionary, name",
|
|
52
|
+
dictionaries: "++, title, version",
|
|
53
|
+
termMeta: "++, dictionary, expression",
|
|
54
|
+
kanjiMeta: "++, dictionary, character",
|
|
55
|
+
media: "++id, dictionary, path"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const OBJECT_STORE_NAMES = [
|
|
60
|
+
"dictionaries",
|
|
61
|
+
"terms",
|
|
62
|
+
"termMeta",
|
|
63
|
+
"kanji",
|
|
64
|
+
"kanjiMeta",
|
|
65
|
+
"tagMeta",
|
|
66
|
+
"media"
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/database/dictionary-database.ts
|
|
71
|
+
var DictionaryDB = class {
|
|
72
|
+
_db;
|
|
73
|
+
_isOpen;
|
|
74
|
+
constructor(dbName = "dict") {
|
|
75
|
+
this._db = new YomitanDatabase(dbName);
|
|
76
|
+
this._isOpen = false;
|
|
77
|
+
}
|
|
78
|
+
async open() {
|
|
79
|
+
await this._db.open();
|
|
80
|
+
this._isOpen = true;
|
|
81
|
+
}
|
|
82
|
+
close() {
|
|
83
|
+
this._db.close();
|
|
84
|
+
this._isOpen = false;
|
|
85
|
+
}
|
|
86
|
+
get isOpen() {
|
|
87
|
+
return this._isOpen;
|
|
88
|
+
}
|
|
89
|
+
get dexie() {
|
|
90
|
+
return this._db;
|
|
91
|
+
}
|
|
92
|
+
async purge() {
|
|
93
|
+
if (this._isOpen) this.close();
|
|
94
|
+
try {
|
|
95
|
+
await this._db.delete();
|
|
96
|
+
} catch (e) {
|
|
97
|
+
require_log.log.error(e);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
this._db = new YomitanDatabase(this._db.name);
|
|
101
|
+
await this.open();
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
async deleteDictionary(dictionaryName, onProgress) {
|
|
105
|
+
const targets = [
|
|
106
|
+
["kanji", "dictionary"],
|
|
107
|
+
["kanjiMeta", "dictionary"],
|
|
108
|
+
["terms", "dictionary"],
|
|
109
|
+
["termMeta", "dictionary"],
|
|
110
|
+
["tagMeta", "dictionary"],
|
|
111
|
+
["media", "dictionary"]
|
|
112
|
+
];
|
|
113
|
+
const progressData = {
|
|
114
|
+
count: 0,
|
|
115
|
+
processed: 0,
|
|
116
|
+
storeCount: targets.length + 1,
|
|
117
|
+
storesProcesed: 0
|
|
118
|
+
};
|
|
119
|
+
for (const [storeName] of targets) {
|
|
120
|
+
const table = this._db.table(storeName);
|
|
121
|
+
const keys = await table.where("dictionary").equals(dictionaryName).primaryKeys();
|
|
122
|
+
progressData.storesProcesed++;
|
|
123
|
+
progressData.count += keys.length;
|
|
124
|
+
onProgress?.(progressData);
|
|
125
|
+
const batchSize = 1e3;
|
|
126
|
+
for (let i = 0; i < keys.length; i += batchSize) {
|
|
127
|
+
const batch = keys.slice(i, i + batchSize);
|
|
128
|
+
await table.bulkDelete(batch);
|
|
129
|
+
progressData.processed += batch.length;
|
|
130
|
+
onProgress?.(progressData);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
await this._db.dictionaries.where("title").equals(dictionaryName).delete();
|
|
134
|
+
progressData.storesProcesed++;
|
|
135
|
+
onProgress?.(progressData);
|
|
136
|
+
}
|
|
137
|
+
async findTermsBulk(termList, dictionaries, matchType) {
|
|
138
|
+
if (termList.length === 0) return [];
|
|
139
|
+
const visited = new Set();
|
|
140
|
+
const results = [];
|
|
141
|
+
const indexNames = matchType === "suffix" ? ["expressionReverse", "readingReverse"] : ["expression", "reading"];
|
|
142
|
+
for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {
|
|
143
|
+
const item = termList[itemIndex];
|
|
144
|
+
for (let indexIndex = 0; indexIndex < indexNames.length; indexIndex++) {
|
|
145
|
+
const indexName = indexNames[indexIndex];
|
|
146
|
+
let query;
|
|
147
|
+
switch (matchType) {
|
|
148
|
+
case "prefix":
|
|
149
|
+
query = this._db.terms.where(indexName).startsWith(item);
|
|
150
|
+
break;
|
|
151
|
+
case "suffix": {
|
|
152
|
+
const reversed = require_utilities.stringReverse(item);
|
|
153
|
+
query = this._db.terms.where(indexName).startsWith(reversed);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
default:
|
|
157
|
+
query = this._db.terms.where(indexName).equals(item);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
const rows = await query.toArray();
|
|
161
|
+
for (const row of rows) {
|
|
162
|
+
if (!dictionaries.has(row.dictionary)) continue;
|
|
163
|
+
const { id } = row;
|
|
164
|
+
if (visited.has(id)) continue;
|
|
165
|
+
visited.add(id);
|
|
166
|
+
const matchSourceIsTerm = indexIndex === 0;
|
|
167
|
+
const matchSource = matchSourceIsTerm ? "term" : "reading";
|
|
168
|
+
const actualMatchType = (matchSourceIsTerm ? row.expression : row.reading) === item ? "exact" : matchType;
|
|
169
|
+
results.push(this._createTerm(matchSource, actualMatchType, row, itemIndex));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return results;
|
|
174
|
+
}
|
|
175
|
+
async findTermsExactBulk(termList, dictionaries) {
|
|
176
|
+
if (termList.length === 0) return [];
|
|
177
|
+
const results = [];
|
|
178
|
+
for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {
|
|
179
|
+
const item = termList[itemIndex];
|
|
180
|
+
const rows = await this._db.terms.where("expression").equals(item.term).toArray();
|
|
181
|
+
for (const row of rows) {
|
|
182
|
+
if (row.reading !== item.reading || !dictionaries.has(row.dictionary)) continue;
|
|
183
|
+
results.push(this._createTerm("term", "exact", row, itemIndex));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return results;
|
|
187
|
+
}
|
|
188
|
+
async findTermsBySequenceBulk(items) {
|
|
189
|
+
if (items.length === 0) return [];
|
|
190
|
+
const results = [];
|
|
191
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
192
|
+
const item = items[itemIndex];
|
|
193
|
+
const rows = await this._db.terms.where("sequence").equals(item.query).toArray();
|
|
194
|
+
for (const row of rows) {
|
|
195
|
+
if (row.dictionary !== item.dictionary) continue;
|
|
196
|
+
results.push(this._createTerm("sequence", "exact", row, itemIndex));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return results;
|
|
200
|
+
}
|
|
201
|
+
async findTermMetaBulk(termList, dictionaries) {
|
|
202
|
+
if (termList.length === 0) return [];
|
|
203
|
+
const results = [];
|
|
204
|
+
for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {
|
|
205
|
+
const term = termList[itemIndex];
|
|
206
|
+
const rows = await this._db.termMeta.where("expression").equals(term).toArray();
|
|
207
|
+
for (const row of rows) {
|
|
208
|
+
if (!dictionaries.has(row.dictionary)) continue;
|
|
209
|
+
results.push(this._createTermMeta(row, itemIndex));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
214
|
+
async findKanjiBulk(kanjiList, dictionaries) {
|
|
215
|
+
if (kanjiList.length === 0) return [];
|
|
216
|
+
const results = [];
|
|
217
|
+
for (let itemIndex = 0; itemIndex < kanjiList.length; itemIndex++) {
|
|
218
|
+
const character = kanjiList[itemIndex];
|
|
219
|
+
const rows = await this._db.kanji.where("character").equals(character).toArray();
|
|
220
|
+
for (const row of rows) {
|
|
221
|
+
if (!dictionaries.has(row.dictionary)) continue;
|
|
222
|
+
results.push(this._createKanji(row, itemIndex));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return results;
|
|
226
|
+
}
|
|
227
|
+
async findKanjiMetaBulk(kanjiList, dictionaries) {
|
|
228
|
+
if (kanjiList.length === 0) return [];
|
|
229
|
+
const results = [];
|
|
230
|
+
for (let itemIndex = 0; itemIndex < kanjiList.length; itemIndex++) {
|
|
231
|
+
const character = kanjiList[itemIndex];
|
|
232
|
+
const rows = await this._db.kanjiMeta.where("character").equals(character).toArray();
|
|
233
|
+
for (const row of rows) {
|
|
234
|
+
if (!dictionaries.has(row.dictionary)) continue;
|
|
235
|
+
results.push({
|
|
236
|
+
index: itemIndex,
|
|
237
|
+
character: row.character,
|
|
238
|
+
mode: row.mode,
|
|
239
|
+
data: row.data,
|
|
240
|
+
dictionary: row.dictionary
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return results;
|
|
245
|
+
}
|
|
246
|
+
async findTagMetaBulk(items) {
|
|
247
|
+
const results = new Array(items.length);
|
|
248
|
+
for (let i = 0; i < items.length; i++) {
|
|
249
|
+
const item = items[i];
|
|
250
|
+
const row = await this._db.tagMeta.where("name").equals(item.query).and((r) => r.dictionary === item.dictionary).first();
|
|
251
|
+
results[i] = row;
|
|
252
|
+
}
|
|
253
|
+
return results;
|
|
254
|
+
}
|
|
255
|
+
async findTagForTitle(name, dictionary) {
|
|
256
|
+
return await this._db.tagMeta.where("name").equals(name).and((row) => row.dictionary === dictionary).first();
|
|
257
|
+
}
|
|
258
|
+
async getMedia(items) {
|
|
259
|
+
if (items.length === 0) return [];
|
|
260
|
+
const results = [];
|
|
261
|
+
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
262
|
+
const item = items[itemIndex];
|
|
263
|
+
const rows = await this._db.media.where("path").equals(item.path).toArray();
|
|
264
|
+
for (const row of rows) {
|
|
265
|
+
if (row.dictionary !== item.dictionary) continue;
|
|
266
|
+
results.push({
|
|
267
|
+
index: itemIndex,
|
|
268
|
+
dictionary: row.dictionary,
|
|
269
|
+
path: row.path,
|
|
270
|
+
mediaType: row.mediaType,
|
|
271
|
+
width: row.width,
|
|
272
|
+
height: row.height,
|
|
273
|
+
content: row.content
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return results;
|
|
278
|
+
}
|
|
279
|
+
async getDictionaryInfo() {
|
|
280
|
+
return await this._db.dictionaries.toArray();
|
|
281
|
+
}
|
|
282
|
+
async getDictionaryCounts(dictionaryNames, getTotal) {
|
|
283
|
+
const storeNames = [
|
|
284
|
+
["kanji", "dictionary"],
|
|
285
|
+
["kanjiMeta", "dictionary"],
|
|
286
|
+
["terms", "dictionary"],
|
|
287
|
+
["termMeta", "dictionary"],
|
|
288
|
+
["tagMeta", "dictionary"],
|
|
289
|
+
["media", "dictionary"]
|
|
290
|
+
];
|
|
291
|
+
const counts = [];
|
|
292
|
+
let total = null;
|
|
293
|
+
if (getTotal) {
|
|
294
|
+
const totalGroup = {};
|
|
295
|
+
for (const [storeName] of storeNames) totalGroup[storeName] = await this._db.table(storeName).count();
|
|
296
|
+
total = totalGroup;
|
|
297
|
+
}
|
|
298
|
+
for (const dictionaryName of dictionaryNames) {
|
|
299
|
+
const countGroup = {};
|
|
300
|
+
for (const [storeName] of storeNames) countGroup[storeName] = await this._db.table(storeName).where("dictionary").equals(dictionaryName).count();
|
|
301
|
+
counts.push(countGroup);
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
total,
|
|
305
|
+
counts
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
async dictionaryExists(title) {
|
|
309
|
+
const result = await this._db.dictionaries.where("title").equals(title).first();
|
|
310
|
+
return result !== void 0;
|
|
311
|
+
}
|
|
312
|
+
async bulkAdd(objectStoreName, items, start, count) {
|
|
313
|
+
if (start + count > items.length) count = items.length - start;
|
|
314
|
+
if (count <= 0) return;
|
|
315
|
+
const table = this._db.table(objectStoreName);
|
|
316
|
+
const batch = items.slice(start, start + count);
|
|
317
|
+
await table.bulkAdd(batch);
|
|
318
|
+
}
|
|
319
|
+
async addWithResult(objectStoreName, item) {
|
|
320
|
+
const table = this._db.table(objectStoreName);
|
|
321
|
+
return await table.add(item);
|
|
322
|
+
}
|
|
323
|
+
async bulkUpdate(objectStoreName, items, start, count) {
|
|
324
|
+
if (start + count > items.length) count = items.length - start;
|
|
325
|
+
if (count <= 0) return;
|
|
326
|
+
const table = this._db.table(objectStoreName);
|
|
327
|
+
const batch = items.slice(start, start + count);
|
|
328
|
+
await table.bulkPut(batch.map((item) => item.data), batch.map((item) => item.primaryKey));
|
|
329
|
+
}
|
|
330
|
+
_createTerm(matchSource, matchType, row, index) {
|
|
331
|
+
const { sequence } = row;
|
|
332
|
+
return {
|
|
333
|
+
index,
|
|
334
|
+
matchType,
|
|
335
|
+
matchSource,
|
|
336
|
+
term: row.expression,
|
|
337
|
+
reading: row.reading,
|
|
338
|
+
definitionTags: this._splitField(row.definitionTags || row.tags),
|
|
339
|
+
termTags: this._splitField(row.termTags),
|
|
340
|
+
rules: this._splitField(row.rules),
|
|
341
|
+
definitions: row.glossary,
|
|
342
|
+
score: row.score,
|
|
343
|
+
dictionary: row.dictionary,
|
|
344
|
+
id: row.id,
|
|
345
|
+
sequence: typeof sequence === "number" ? sequence : -1
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
_createTermMeta(row, index) {
|
|
349
|
+
const { expression: term, mode, data, dictionary } = row;
|
|
350
|
+
switch (mode) {
|
|
351
|
+
case "freq": return {
|
|
352
|
+
index,
|
|
353
|
+
term,
|
|
354
|
+
mode,
|
|
355
|
+
data,
|
|
356
|
+
dictionary
|
|
357
|
+
};
|
|
358
|
+
case "pitch": return {
|
|
359
|
+
index,
|
|
360
|
+
term,
|
|
361
|
+
mode,
|
|
362
|
+
data,
|
|
363
|
+
dictionary
|
|
364
|
+
};
|
|
365
|
+
case "ipa": return {
|
|
366
|
+
index,
|
|
367
|
+
term,
|
|
368
|
+
mode,
|
|
369
|
+
data,
|
|
370
|
+
dictionary
|
|
371
|
+
};
|
|
372
|
+
default: throw new Error(`Unknown mode: ${mode}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
_createKanji(row, index) {
|
|
376
|
+
const { stats } = row;
|
|
377
|
+
return {
|
|
378
|
+
index,
|
|
379
|
+
character: row.character,
|
|
380
|
+
onyomi: this._splitField(row.onyomi),
|
|
381
|
+
kunyomi: this._splitField(row.kunyomi),
|
|
382
|
+
tags: this._splitField(row.tags),
|
|
383
|
+
definitions: row.meanings,
|
|
384
|
+
stats: typeof stats === "object" && stats !== null ? stats : {},
|
|
385
|
+
dictionary: row.dictionary
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
_splitField(field) {
|
|
389
|
+
return typeof field === "string" && field.length > 0 ? field.split(" ") : [];
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
//#endregion
|
|
394
|
+
Object.defineProperty(exports, 'DictionaryDB', {
|
|
395
|
+
enumerable: true,
|
|
396
|
+
get: function () {
|
|
397
|
+
return DictionaryDB;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
Object.defineProperty(exports, 'OBJECT_STORE_NAMES', {
|
|
401
|
+
enumerable: true,
|
|
402
|
+
get: function () {
|
|
403
|
+
return OBJECT_STORE_NAMES;
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
Object.defineProperty(exports, 'YomitanDatabase', {
|
|
407
|
+
enumerable: true,
|
|
408
|
+
get: function () {
|
|
409
|
+
return YomitanDatabase;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
//# sourceMappingURL=dictionary-database-lvFvftnO.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictionary-database-lvFvftnO.cjs","names":["Dexie","OBJECT_STORE_NAMES: ObjectStoreName[]","dictionaryName: string","onProgress?: DictionaryDatabase.DeleteDictionaryProgressCallback","targets: [string, string][]","progressData: DictionaryDatabase.DeleteDictionaryProgressData","termList: string[]","dictionaries: DictionaryDatabase.DictionarySet","matchType: DictionaryDatabase.MatchType","results: DictionaryDatabase.TermEntry[]","matchSource: DictionaryDatabase.MatchSource","actualMatchType: DictionaryDatabase.MatchType","termList: DictionaryDatabase.TermExactRequest[]","items: DictionaryDatabase.DictionaryAndQueryRequest[]","results: DictionaryDatabase.TermMeta[]","kanjiList: string[]","results: DictionaryDatabase.KanjiEntry[]","results: DictionaryDatabase.KanjiMeta[]","results: (DictionaryDatabase.Tag | undefined)[]","r: DictionaryDatabase.Tag","name: string","dictionary: string","row: DictionaryDatabase.Tag","items: DictionaryDatabase.MediaRequest[]","results: DictionaryDatabase.Media[]","dictionaryNames: string[]","getTotal: boolean","storeNames: [string, string][]","counts: DictionaryDatabase.DictionaryCountGroup[]","total: DictionaryDatabase.DictionaryCountGroup | null","totalGroup: DictionaryDatabase.DictionaryCountGroup","countGroup: DictionaryDatabase.DictionaryCountGroup","title: string","objectStoreName: DictionaryDatabase.ObjectStoreName","items: unknown[]","start: number","count: number","item: unknown","items: { primaryKey: number; data: unknown }[]","row: DictionaryDatabase.DatabaseTermEntryWithId","index: number","row: DictionaryDatabase.DatabaseTermMeta","row: DictionaryDatabase.DatabaseKanjiEntry","field: unknown"],"sources":["../src/database/schema.ts","../src/database/dictionary-database.ts"],"sourcesContent":["import Dexie from 'dexie';\nimport type { ObjectStoreName } from '../types/dictionary-database';\n\nexport class YomitanDatabase extends Dexie {\n terms!: Dexie.Table;\n termMeta!: Dexie.Table;\n kanji!: Dexie.Table;\n kanjiMeta!: Dexie.Table;\n tagMeta!: Dexie.Table;\n dictionaries!: Dexie.Table;\n media!: Dexie.Table;\n\n constructor(name = 'dict') {\n super(name);\n\n this.version(20).stores({\n terms: '++id, dictionary, expression, reading',\n kanji: '++, dictionary, character',\n tagMeta: '++, dictionary',\n dictionaries: '++, title, version',\n });\n\n this.version(30).stores({\n terms: '++id, dictionary, expression, reading',\n kanji: '++, dictionary, character',\n tagMeta: '++, dictionary, name',\n dictionaries: '++, title, version',\n termMeta: '++, dictionary, expression',\n kanjiMeta: '++, dictionary, character',\n });\n\n this.version(40).stores({\n terms: '++id, dictionary, expression, reading, sequence',\n kanji: '++, dictionary, character',\n tagMeta: '++, dictionary, name',\n dictionaries: '++, title, version',\n termMeta: '++, dictionary, expression',\n kanjiMeta: '++, dictionary, character',\n });\n\n this.version(50).stores({\n terms: '++id, dictionary, expression, reading, sequence, expressionReverse, readingReverse',\n kanji: '++, dictionary, character',\n tagMeta: '++, dictionary, name',\n dictionaries: '++, title, version',\n termMeta: '++, dictionary, expression',\n kanjiMeta: '++, dictionary, character',\n });\n\n this.version(60).stores({\n terms: '++id, dictionary, expression, reading, sequence, expressionReverse, readingReverse',\n kanji: '++, dictionary, character',\n tagMeta: '++, dictionary, name',\n dictionaries: '++, title, version',\n termMeta: '++, dictionary, expression',\n kanjiMeta: '++, dictionary, character',\n media: '++id, dictionary, path',\n });\n }\n}\n\nexport const OBJECT_STORE_NAMES: ObjectStoreName[] = [\n 'dictionaries',\n 'terms',\n 'termMeta',\n 'kanji',\n 'kanjiMeta',\n 'tagMeta',\n 'media',\n];\n","import type * as DictionaryDatabase from '../types/dictionary-database';\nimport type * as DictionaryImporter from '../types/dictionary-importer';\nimport { log } from '../util/log';\nimport { stringReverse } from '../util/utilities';\nimport { OBJECT_STORE_NAMES, YomitanDatabase } from './schema';\n\nexport class DictionaryDB {\n private _db: YomitanDatabase;\n private _isOpen: boolean;\n\n constructor(dbName = 'dict') {\n this._db = new YomitanDatabase(dbName);\n this._isOpen = false;\n }\n\n async open(): Promise<void> {\n await this._db.open();\n this._isOpen = true;\n }\n\n close(): void {\n this._db.close();\n this._isOpen = false;\n }\n\n get isOpen(): boolean {\n return this._isOpen;\n }\n\n get dexie(): YomitanDatabase {\n return this._db;\n }\n\n async purge(): Promise<boolean> {\n if (this._isOpen) {\n this.close();\n }\n try {\n await this._db.delete();\n } catch (e) {\n log.error(e);\n return false;\n }\n this._db = new YomitanDatabase(this._db.name);\n await this.open();\n return true;\n }\n\n async deleteDictionary(\n dictionaryName: string,\n onProgress?: DictionaryDatabase.DeleteDictionaryProgressCallback,\n ): Promise<void> {\n const targets: [string, string][] = [\n ['kanji', 'dictionary'],\n ['kanjiMeta', 'dictionary'],\n ['terms', 'dictionary'],\n ['termMeta', 'dictionary'],\n ['tagMeta', 'dictionary'],\n ['media', 'dictionary'],\n ];\n\n const progressData: DictionaryDatabase.DeleteDictionaryProgressData = {\n count: 0,\n processed: 0,\n storeCount: targets.length + 1,\n storesProcesed: 0,\n };\n\n for (const [storeName] of targets) {\n const table = this._db.table(storeName);\n const keys = await table.where('dictionary').equals(dictionaryName).primaryKeys();\n progressData.storesProcesed++;\n progressData.count += keys.length;\n onProgress?.(progressData);\n\n const batchSize = 1000;\n for (let i = 0; i < keys.length; i += batchSize) {\n const batch = keys.slice(i, i + batchSize);\n await table.bulkDelete(batch);\n progressData.processed += batch.length;\n onProgress?.(progressData);\n }\n }\n\n // Delete from dictionaries store\n await this._db.dictionaries.where('title').equals(dictionaryName).delete();\n progressData.storesProcesed++;\n onProgress?.(progressData);\n }\n\n async findTermsBulk(\n termList: string[],\n dictionaries: DictionaryDatabase.DictionarySet,\n matchType: DictionaryDatabase.MatchType,\n ): Promise<DictionaryDatabase.TermEntry[]> {\n if (termList.length === 0) {\n return [];\n }\n\n const visited = new Set<number>();\n const results: DictionaryDatabase.TermEntry[] = [];\n\n const indexNames = matchType === 'suffix' ? ['expressionReverse', 'readingReverse'] : ['expression', 'reading'];\n\n for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {\n const item = termList[itemIndex];\n\n for (let indexIndex = 0; indexIndex < indexNames.length; indexIndex++) {\n const indexName = indexNames[indexIndex];\n\n let query;\n switch (matchType) {\n case 'prefix':\n query = this._db.terms.where(indexName).startsWith(item);\n break;\n case 'suffix': {\n const reversed = stringReverse(item);\n query = this._db.terms.where(indexName).startsWith(reversed);\n break;\n }\n default:\n query = this._db.terms.where(indexName).equals(item);\n break;\n }\n\n const rows = await query.toArray();\n\n for (const row of rows) {\n if (!dictionaries.has(row.dictionary)) {\n continue;\n }\n const { id } = row;\n if (visited.has(id)) {\n continue;\n }\n visited.add(id);\n\n const matchSourceIsTerm = indexIndex === 0;\n const matchSource: DictionaryDatabase.MatchSource = matchSourceIsTerm ? 'term' : 'reading';\n const actualMatchType: DictionaryDatabase.MatchType =\n (matchSourceIsTerm ? row.expression : row.reading) === item ? 'exact' : matchType;\n\n results.push(this._createTerm(matchSource, actualMatchType, row, itemIndex));\n }\n }\n }\n\n return results;\n }\n\n async findTermsExactBulk(\n termList: DictionaryDatabase.TermExactRequest[],\n dictionaries: DictionaryDatabase.DictionarySet,\n ): Promise<DictionaryDatabase.TermEntry[]> {\n if (termList.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.TermEntry[] = [];\n\n for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {\n const item = termList[itemIndex];\n const rows = await this._db.terms.where('expression').equals(item.term).toArray();\n\n for (const row of rows) {\n if (row.reading !== item.reading || !dictionaries.has(row.dictionary)) {\n continue;\n }\n results.push(this._createTerm('term', 'exact', row, itemIndex));\n }\n }\n\n return results;\n }\n\n async findTermsBySequenceBulk(\n items: DictionaryDatabase.DictionaryAndQueryRequest[],\n ): Promise<DictionaryDatabase.TermEntry[]> {\n if (items.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.TermEntry[] = [];\n\n for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n const item = items[itemIndex];\n const rows = await this._db.terms.where('sequence').equals(item.query).toArray();\n\n for (const row of rows) {\n if (row.dictionary !== item.dictionary) {\n continue;\n }\n results.push(this._createTerm('sequence', 'exact', row, itemIndex));\n }\n }\n\n return results;\n }\n\n async findTermMetaBulk(\n termList: string[],\n dictionaries: DictionaryDatabase.DictionarySet,\n ): Promise<DictionaryDatabase.TermMeta[]> {\n if (termList.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.TermMeta[] = [];\n\n for (let itemIndex = 0; itemIndex < termList.length; itemIndex++) {\n const term = termList[itemIndex];\n const rows = await this._db.termMeta.where('expression').equals(term).toArray();\n\n for (const row of rows) {\n if (!dictionaries.has(row.dictionary)) {\n continue;\n }\n results.push(this._createTermMeta(row, itemIndex));\n }\n }\n\n return results;\n }\n\n async findKanjiBulk(\n kanjiList: string[],\n dictionaries: DictionaryDatabase.DictionarySet,\n ): Promise<DictionaryDatabase.KanjiEntry[]> {\n if (kanjiList.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.KanjiEntry[] = [];\n\n for (let itemIndex = 0; itemIndex < kanjiList.length; itemIndex++) {\n const character = kanjiList[itemIndex];\n const rows = await this._db.kanji.where('character').equals(character).toArray();\n\n for (const row of rows) {\n if (!dictionaries.has(row.dictionary)) {\n continue;\n }\n results.push(this._createKanji(row, itemIndex));\n }\n }\n\n return results;\n }\n\n async findKanjiMetaBulk(\n kanjiList: string[],\n dictionaries: DictionaryDatabase.DictionarySet,\n ): Promise<DictionaryDatabase.KanjiMeta[]> {\n if (kanjiList.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.KanjiMeta[] = [];\n\n for (let itemIndex = 0; itemIndex < kanjiList.length; itemIndex++) {\n const character = kanjiList[itemIndex];\n const rows = await this._db.kanjiMeta.where('character').equals(character).toArray();\n\n for (const row of rows) {\n if (!dictionaries.has(row.dictionary)) {\n continue;\n }\n results.push({\n index: itemIndex,\n character: row.character,\n mode: row.mode,\n data: row.data,\n dictionary: row.dictionary,\n });\n }\n }\n\n return results;\n }\n\n async findTagMetaBulk(\n items: DictionaryDatabase.DictionaryAndQueryRequest[],\n ): Promise<(DictionaryDatabase.Tag | undefined)[]> {\n const results: (DictionaryDatabase.Tag | undefined)[] = new Array(items.length);\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const row = await this._db.tagMeta\n .where('name')\n .equals(item.query)\n .and((r: DictionaryDatabase.Tag) => r.dictionary === item.dictionary)\n .first();\n results[i] = row;\n }\n\n return results;\n }\n\n async findTagForTitle(name: string, dictionary: string): Promise<DictionaryDatabase.Tag | undefined> {\n return await this._db.tagMeta\n .where('name')\n .equals(name)\n .and((row: DictionaryDatabase.Tag) => row.dictionary === dictionary)\n .first();\n }\n\n async getMedia(items: DictionaryDatabase.MediaRequest[]): Promise<DictionaryDatabase.Media[]> {\n if (items.length === 0) {\n return [];\n }\n\n const results: DictionaryDatabase.Media[] = [];\n\n for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n const item = items[itemIndex];\n const rows = await this._db.media.where('path').equals(item.path).toArray();\n\n for (const row of rows) {\n if (row.dictionary !== item.dictionary) {\n continue;\n }\n results.push({\n index: itemIndex,\n dictionary: row.dictionary,\n path: row.path,\n mediaType: row.mediaType,\n width: row.width,\n height: row.height,\n content: row.content,\n });\n }\n }\n\n return results;\n }\n\n async getDictionaryInfo(): Promise<DictionaryImporter.Summary[]> {\n return await this._db.dictionaries.toArray();\n }\n\n async getDictionaryCounts(\n dictionaryNames: string[],\n getTotal: boolean,\n ): Promise<DictionaryDatabase.DictionaryCounts> {\n const storeNames: [string, string][] = [\n ['kanji', 'dictionary'],\n ['kanjiMeta', 'dictionary'],\n ['terms', 'dictionary'],\n ['termMeta', 'dictionary'],\n ['tagMeta', 'dictionary'],\n ['media', 'dictionary'],\n ];\n\n const counts: DictionaryDatabase.DictionaryCountGroup[] = [];\n\n let total: DictionaryDatabase.DictionaryCountGroup | null = null;\n if (getTotal) {\n const totalGroup: DictionaryDatabase.DictionaryCountGroup = {};\n for (const [storeName] of storeNames) {\n totalGroup[storeName] = await this._db.table(storeName).count();\n }\n total = totalGroup;\n }\n\n for (const dictionaryName of dictionaryNames) {\n const countGroup: DictionaryDatabase.DictionaryCountGroup = {};\n for (const [storeName] of storeNames) {\n countGroup[storeName] = await this._db\n .table(storeName)\n .where('dictionary')\n .equals(dictionaryName)\n .count();\n }\n counts.push(countGroup);\n }\n\n return { total, counts };\n }\n\n async dictionaryExists(title: string): Promise<boolean> {\n const result = await this._db.dictionaries.where('title').equals(title).first();\n return result !== undefined;\n }\n\n async bulkAdd(\n objectStoreName: DictionaryDatabase.ObjectStoreName,\n items: unknown[],\n start: number,\n count: number,\n ): Promise<void> {\n if (start + count > items.length) {\n count = items.length - start;\n }\n if (count <= 0) {\n return;\n }\n\n const table = this._db.table(objectStoreName);\n const batch = items.slice(start, start + count);\n await table.bulkAdd(batch);\n }\n\n async addWithResult(objectStoreName: DictionaryDatabase.ObjectStoreName, item: unknown): Promise<number> {\n const table = this._db.table(objectStoreName);\n return (await table.add(item)) as number;\n }\n\n async bulkUpdate(\n objectStoreName: DictionaryDatabase.ObjectStoreName,\n items: { primaryKey: number; data: unknown }[],\n start: number,\n count: number,\n ): Promise<void> {\n if (start + count > items.length) {\n count = items.length - start;\n }\n if (count <= 0) {\n return;\n }\n\n const table = this._db.table(objectStoreName);\n const batch = items.slice(start, start + count);\n await table.bulkPut(batch.map((item) => item.data), batch.map((item) => item.primaryKey));\n }\n\n // Private result creators\n\n private _createTerm(\n matchSource: DictionaryDatabase.MatchSource,\n matchType: DictionaryDatabase.MatchType,\n row: DictionaryDatabase.DatabaseTermEntryWithId,\n index: number,\n ): DictionaryDatabase.TermEntry {\n const { sequence } = row;\n return {\n index,\n matchType,\n matchSource,\n term: row.expression,\n reading: row.reading,\n definitionTags: this._splitField(row.definitionTags || row.tags),\n termTags: this._splitField(row.termTags),\n rules: this._splitField(row.rules),\n definitions: row.glossary,\n score: row.score,\n dictionary: row.dictionary,\n id: row.id,\n sequence: typeof sequence === 'number' ? sequence : -1,\n };\n }\n\n private _createTermMeta(row: DictionaryDatabase.DatabaseTermMeta, index: number): DictionaryDatabase.TermMeta {\n const { expression: term, mode, data, dictionary } = row;\n switch (mode) {\n case 'freq':\n return { index, term, mode, data, dictionary };\n case 'pitch':\n return { index, term, mode, data, dictionary };\n case 'ipa':\n return { index, term, mode, data, dictionary };\n default:\n throw new Error(`Unknown mode: ${mode}`);\n }\n }\n\n private _createKanji(row: DictionaryDatabase.DatabaseKanjiEntry, index: number): DictionaryDatabase.KanjiEntry {\n const { stats } = row;\n return {\n index,\n character: row.character,\n onyomi: this._splitField(row.onyomi),\n kunyomi: this._splitField(row.kunyomi),\n tags: this._splitField(row.tags),\n definitions: row.meanings,\n stats: typeof stats === 'object' && stats !== null ? stats : {},\n dictionary: row.dictionary,\n };\n }\n\n private _splitField(field: unknown): string[] {\n return typeof field === 'string' && field.length > 0 ? field.split(' ') : [];\n }\n}\n"],"mappings":"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"}
|