book-index-ui 0.2.12 → 0.2.13
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/dist/index.cjs +3 -3
- package/dist/index.d.ts +4 -0
- package/dist/index.js +757 -760
- package/dist/{storage-entry-sPrgfaS5.cjs → storage-entry-QB1IoDUU.cjs} +1 -1
- package/dist/{storage-entry-CWocbrbM.js → storage-entry-UQLfmeLb.js} +250 -221
- package/dist/storage.cjs +1 -1
- package/dist/storage.d.ts +4 -0
- package/dist/storage.js +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
const ct = { official: 0, draft: 1 }, lt = { 0: "official", 1: "draft" }, ht = { book: 0, collection: 2, work: 3, entity: 4 }, ut = { 0: "book", 2: "collection", 3: "work", 4: "entity" }, V = 62n, X = 59n, Q = 19n, Z = 8n, tt = (1n << 40n) - 1n, dt = (1n << 3n) - 1n, ft = (1n << 11n) - 1n, yt = (1n << 8n) - 1n, R = "0123456789abcdefghijklmnopqrstuvwxyz", et = /* @__PURE__ */ new Map();
|
|
2
|
-
for (let
|
|
3
|
-
et.set(R[
|
|
4
|
-
function
|
|
5
|
-
if (
|
|
2
|
+
for (let c = 0; c < R.length; c++)
|
|
3
|
+
et.set(R[c], BigInt(c));
|
|
4
|
+
function D(c) {
|
|
5
|
+
if (c === 0n) return R[0];
|
|
6
6
|
let t = "";
|
|
7
|
-
for (;
|
|
8
|
-
t = R[Number(
|
|
7
|
+
for (; c > 0n; )
|
|
8
|
+
t = R[Number(c % 36n)] + t, c = c / 36n;
|
|
9
9
|
return t;
|
|
10
10
|
}
|
|
11
|
-
function st(
|
|
11
|
+
function st(c) {
|
|
12
12
|
let t = 0n;
|
|
13
|
-
for (const e of
|
|
13
|
+
for (const e of c) {
|
|
14
14
|
const s = et.get(e);
|
|
15
15
|
if (s === void 0)
|
|
16
16
|
throw new Error(`Invalid Base36 character: ${e}`);
|
|
@@ -19,11 +19,11 @@ function st(r) {
|
|
|
19
19
|
return t;
|
|
20
20
|
}
|
|
21
21
|
const H = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", nt = /* @__PURE__ */ new Map();
|
|
22
|
-
for (let
|
|
23
|
-
nt.set(H[
|
|
24
|
-
function gt(
|
|
22
|
+
for (let c = 0; c < H.length; c++)
|
|
23
|
+
nt.set(H[c], BigInt(c));
|
|
24
|
+
function gt(c) {
|
|
25
25
|
let t = 0n;
|
|
26
|
-
for (const e of
|
|
26
|
+
for (const e of c) {
|
|
27
27
|
const s = nt.get(e);
|
|
28
28
|
if (s === void 0)
|
|
29
29
|
throw new Error(`Invalid Base58 character: ${e}`);
|
|
@@ -31,12 +31,12 @@ function gt(r) {
|
|
|
31
31
|
}
|
|
32
32
|
return t;
|
|
33
33
|
}
|
|
34
|
-
function x(
|
|
35
|
-
return /[A-Z]/.test(
|
|
34
|
+
function x(c) {
|
|
35
|
+
return /[A-Z]/.test(c) ? gt(c) : st(c);
|
|
36
36
|
}
|
|
37
|
-
const
|
|
38
|
-
function $(
|
|
39
|
-
const t = Number(
|
|
37
|
+
const jt = D, Pt = st;
|
|
38
|
+
function $(c) {
|
|
39
|
+
const t = Number(c >> V & 1n), e = Number(c >> X & dt), s = c >> Q & tt, n = Number(c >> Z & ft), i = Number(c & yt);
|
|
40
40
|
return {
|
|
41
41
|
status: lt[t] ?? "draft",
|
|
42
42
|
type: ut[e] ?? "book",
|
|
@@ -45,31 +45,31 @@ function $(r) {
|
|
|
45
45
|
sequence: i
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
function z(
|
|
49
|
-
return BigInt(ct[
|
|
48
|
+
function z(c, t, e, s, n) {
|
|
49
|
+
return BigInt(ct[c]) << V | BigInt(ht[t]) << X | (e & tt) << Q | BigInt(s) << Z | BigInt(n);
|
|
50
50
|
}
|
|
51
|
-
function
|
|
52
|
-
return $(x(
|
|
51
|
+
function L(c) {
|
|
52
|
+
return $(x(c));
|
|
53
53
|
}
|
|
54
|
-
function
|
|
55
|
-
return
|
|
54
|
+
function pt(c) {
|
|
55
|
+
return L(c).type;
|
|
56
56
|
}
|
|
57
|
-
function
|
|
58
|
-
return
|
|
57
|
+
function Tt(c) {
|
|
58
|
+
return L(c).status;
|
|
59
59
|
}
|
|
60
|
-
const N = { book: "Book", collection: "Collection", work: "Work", entity: "Entity" },
|
|
61
|
-
function J(
|
|
60
|
+
const N = { book: "Book", collection: "Collection", work: "Work", entity: "Entity" }, mt = { Book: "book", Collection: "collection", Work: "work", Entity: "entity" }, T = 16;
|
|
61
|
+
function J(c, t = T) {
|
|
62
62
|
let e = 0;
|
|
63
|
-
for (let s = 0; s <
|
|
64
|
-
e = Math.imul(e, 31) +
|
|
63
|
+
for (let s = 0; s < c.length; s++)
|
|
64
|
+
e = Math.imul(e, 31) + c.charCodeAt(s) >>> 0;
|
|
65
65
|
return e % t;
|
|
66
66
|
}
|
|
67
|
-
function b(...
|
|
68
|
-
const t =
|
|
67
|
+
function b(...c) {
|
|
68
|
+
const t = c.join("/");
|
|
69
69
|
return t.startsWith("//") ? "//" + t.slice(2).replace(/\/+/g, "/") : t.replace(/\/+/g, "/");
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
return
|
|
71
|
+
function _t(c) {
|
|
72
|
+
return c.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, "") || "Undefined";
|
|
73
73
|
}
|
|
74
74
|
class it {
|
|
75
75
|
constructor(t, e) {
|
|
@@ -86,23 +86,23 @@ class it {
|
|
|
86
86
|
* 计算文件路径: {root}/{Type}/{c1}/{c2}/{c3}/{ID}-{name}.json
|
|
87
87
|
*/
|
|
88
88
|
getPath(t, e, s) {
|
|
89
|
-
const n = this.getRootById(e), i = e.padEnd(3, "_").substring(0, 3), [o,
|
|
90
|
-
return b(n, a, o,
|
|
89
|
+
const n = this.getRootById(e), i = e.padEnd(3, "_").substring(0, 3), [o, r, l] = [i[0], i[1], i[2]], a = N[t];
|
|
90
|
+
return b(n, a, o, r, l, `${e}-${_t(s)}.json`);
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* 保存条目并更新索引
|
|
94
94
|
*/
|
|
95
95
|
async saveItem(t, e, s) {
|
|
96
|
-
const n = s.title || s.书名 || "未命名", i = s.edition || "", o = i ? `${n}${i}` : n,
|
|
97
|
-
if (l && l !==
|
|
96
|
+
const n = s.title || s.书名 || "未命名", i = s.edition || "", o = i ? `${n}${i}` : n, r = this.getPath(t, e, o), l = await this.findFileById(e);
|
|
97
|
+
if (l && l !== r)
|
|
98
98
|
try {
|
|
99
99
|
await this.fs.deleteFile(l);
|
|
100
100
|
} catch {
|
|
101
101
|
}
|
|
102
|
-
const a =
|
|
103
|
-
await this.fs.mkdir(a), s.id = e, s.type = t, await this.fs.writeFile(
|
|
104
|
-
const h = this.getRootById(e), u =
|
|
105
|
-
return await this.updateIndexEntry(h, s, t, u),
|
|
102
|
+
const a = r.substring(0, r.lastIndexOf("/"));
|
|
103
|
+
await this.fs.mkdir(a), s.id = e, s.type = t, await this.fs.writeFile(r, JSON.stringify(s, wt, 2));
|
|
104
|
+
const h = this.getRootById(e), u = r.substring(h.length + 1);
|
|
105
|
+
return await this.updateIndexEntry(h, s, t, u), r;
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* 更新索引分片中的条目
|
|
@@ -110,7 +110,7 @@ class it {
|
|
|
110
110
|
async updateIndexEntry(t, e, s, n) {
|
|
111
111
|
const i = e.id || "";
|
|
112
112
|
if (!i) return;
|
|
113
|
-
const o = `${s}s`,
|
|
113
|
+
const o = `${s}s`, r = await this.loadShard(t, o, i);
|
|
114
114
|
let l = "";
|
|
115
115
|
const a = e.authors;
|
|
116
116
|
if (Array.isArray(a) && a.length > 0) {
|
|
@@ -133,9 +133,9 @@ class it {
|
|
|
133
133
|
if (Array.isArray(P))
|
|
134
134
|
for (const y of P) {
|
|
135
135
|
if (typeof y != "object" || y === null) continue;
|
|
136
|
-
const
|
|
137
|
-
if (Array.isArray(
|
|
138
|
-
|
|
136
|
+
const _ = y.types;
|
|
137
|
+
if (Array.isArray(_))
|
|
138
|
+
_.includes("text") && (C = !0), _.includes("image") && (S = !0);
|
|
139
139
|
else {
|
|
140
140
|
const E = y.type;
|
|
141
141
|
(E === "text" || E === "text+image") && (C = !0), (E === "image" || E === "text+image") && (S = !0);
|
|
@@ -151,8 +151,8 @@ class it {
|
|
|
151
151
|
holder: d
|
|
152
152
|
};
|
|
153
153
|
p && p.length > 0 && (m.additional_titles = p), k && k.length > 0 && (m.attached_texts = k), v && (m.juan_count = v), A && (m.measure_info = A);
|
|
154
|
-
const
|
|
155
|
-
|
|
154
|
+
const j = typeof e.edition == "string" ? e.edition : "";
|
|
155
|
+
j && (m.edition = j), C && (m.has_text = !0), S && (m.has_image = !0), r[i] = m, await this.saveShard(t, o, i, r);
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
158
|
* 删除条目和索引记录
|
|
@@ -160,8 +160,8 @@ class it {
|
|
|
160
160
|
async deleteItem(t) {
|
|
161
161
|
const e = await this.findFileById(t);
|
|
162
162
|
if (!e) return !1;
|
|
163
|
-
const s = x(t), n = $(s), i = this.getRootByStatus(n.status), o = `${n.type}s`,
|
|
164
|
-
return
|
|
163
|
+
const s = x(t), n = $(s), i = this.getRootByStatus(n.status), o = `${n.type}s`, r = await this.loadShard(i, o, t);
|
|
164
|
+
return r[t] && (delete r[t], await this.saveShard(i, o, t, r)), await this.fs.deleteFile(e), !0;
|
|
165
165
|
}
|
|
166
166
|
/**
|
|
167
167
|
* 通过 ID 查找文件
|
|
@@ -169,8 +169,8 @@ class it {
|
|
|
169
169
|
async findFileById(t) {
|
|
170
170
|
const e = t.padEnd(3, "_").substring(0, 3), [s, n, i] = [e[0], e[1], e[2]];
|
|
171
171
|
for (const o of [this.officialRoot, this.draftRoot])
|
|
172
|
-
for (const
|
|
173
|
-
const l = b(o,
|
|
172
|
+
for (const r of ["Book", "Collection", "Work"]) {
|
|
173
|
+
const l = b(o, r, s, n, i);
|
|
174
174
|
if (await this.fs.exists(l))
|
|
175
175
|
try {
|
|
176
176
|
const h = (await this.fs.readdir(l)).find((u) => u.startsWith(`${t}-`) && u.endsWith(".json"));
|
|
@@ -206,8 +206,8 @@ class it {
|
|
|
206
206
|
async loadEntries(t, e) {
|
|
207
207
|
const s = e ? [this.getRootByStatus(e)] : [this.officialRoot, this.draftRoot], n = [], i = `${t}s`;
|
|
208
208
|
for (const o of s) {
|
|
209
|
-
const
|
|
210
|
-
for (const [l, a] of Object.entries(
|
|
209
|
+
const r = await this.loadAllShards(o, i);
|
|
210
|
+
for (const [l, a] of Object.entries(r))
|
|
211
211
|
n.push({
|
|
212
212
|
id: l,
|
|
213
213
|
title: a.title,
|
|
@@ -262,14 +262,14 @@ class it {
|
|
|
262
262
|
async rebuildIndex(t) {
|
|
263
263
|
var n, i;
|
|
264
264
|
const e = this.getRootByStatus(t), s = {
|
|
265
|
-
books: Object.fromEntries(Array.from({ length:
|
|
265
|
+
books: Object.fromEntries(Array.from({ length: T }, (o, r) => [r, {}])),
|
|
266
266
|
collections: { 0: {} },
|
|
267
|
-
works: Object.fromEntries(Array.from({ length:
|
|
267
|
+
works: Object.fromEntries(Array.from({ length: T }, (o, r) => [r, {}]))
|
|
268
268
|
};
|
|
269
269
|
for (const o of ["Book", "Collection", "Work"]) {
|
|
270
|
-
const
|
|
271
|
-
if (!await this.fs.exists(
|
|
272
|
-
const a = `${
|
|
270
|
+
const r = b(e, o);
|
|
271
|
+
if (!await this.fs.exists(r)) continue;
|
|
272
|
+
const a = `${mt[o]}s`, h = await this.fs.glob(r, "**/*.json");
|
|
273
273
|
for (const u of h)
|
|
274
274
|
if (!u.includes("/index/"))
|
|
275
275
|
try {
|
|
@@ -292,20 +292,20 @@ class it {
|
|
|
292
292
|
const S = d.juan_count;
|
|
293
293
|
typeof S == "number" ? C = S : typeof S == "object" && S !== null && (C = S.number || void 0);
|
|
294
294
|
const P = typeof d.measure_info == "string" ? d.measure_info : "";
|
|
295
|
-
let m = !1,
|
|
295
|
+
let m = !1, j = !1;
|
|
296
296
|
const y = d.resources;
|
|
297
297
|
if (Array.isArray(y))
|
|
298
298
|
for (const g of y) {
|
|
299
299
|
if (typeof g != "object" || g === null) continue;
|
|
300
|
-
const
|
|
301
|
-
if (Array.isArray(
|
|
302
|
-
|
|
300
|
+
const U = g.types;
|
|
301
|
+
if (Array.isArray(U))
|
|
302
|
+
U.includes("text") && (m = !0), U.includes("image") && (j = !0);
|
|
303
303
|
else {
|
|
304
304
|
const M = g.type;
|
|
305
|
-
(M === "text" || M === "text+image") && (m = !0), (M === "image" || M === "text+image") && (
|
|
305
|
+
(M === "text" || M === "text+image") && (m = !0), (M === "image" || M === "text+image") && (j = !0);
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
-
const
|
|
308
|
+
const _ = {
|
|
309
309
|
id: f,
|
|
310
310
|
title: d.title || "未命名",
|
|
311
311
|
type: o,
|
|
@@ -314,16 +314,16 @@ class it {
|
|
|
314
314
|
year: typeof d.publication_info == "object" && ((n = d.publication_info) == null ? void 0 : n.year) || "",
|
|
315
315
|
holder: typeof d.current_location == "object" && ((i = d.current_location) == null ? void 0 : i.name) || ""
|
|
316
316
|
};
|
|
317
|
-
I && I.length > 0 && (
|
|
317
|
+
I && I.length > 0 && (_.additional_titles = I), A && A.length > 0 && (_.attached_texts = A), C && (_.juan_count = C), P && (_.measure_info = P);
|
|
318
318
|
const E = typeof d.edition == "string" ? d.edition : "";
|
|
319
|
-
E && (
|
|
319
|
+
E && (_.edition = E), m && (_.has_text = !0), j && (_.has_image = !0);
|
|
320
320
|
const rt = a === "collections" ? 0 : J(f);
|
|
321
|
-
s[a][rt][f] =
|
|
321
|
+
s[a][rt][f] = _;
|
|
322
322
|
} catch {
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
for (const [o,
|
|
326
|
-
for (const [l, a] of Object.entries(
|
|
325
|
+
for (const [o, r] of Object.entries(s))
|
|
326
|
+
for (const [l, a] of Object.entries(r)) {
|
|
327
327
|
const h = this.shardPath(e, o, Number(l)), u = h.substring(0, h.lastIndexOf("/"));
|
|
328
328
|
await this.fs.mkdir(u), await this.fs.writeFile(h, JSON.stringify(a, null, 2));
|
|
329
329
|
}
|
|
@@ -334,8 +334,8 @@ class it {
|
|
|
334
334
|
* 与 JSON 文件同级,以 ID 命名
|
|
335
335
|
*/
|
|
336
336
|
getAssetDir(t) {
|
|
337
|
-
const e = this.getRootById(t), s = x(t), i = $(s).type, o = t.padEnd(3, "_").substring(0, 3), [
|
|
338
|
-
return b(e, h,
|
|
337
|
+
const e = this.getRootById(t), s = x(t), i = $(s).type, o = t.padEnd(3, "_").substring(0, 3), [r, l, a] = [o[0], o[1], o[2]], h = N[i];
|
|
338
|
+
return b(e, h, r, l, a, t);
|
|
339
339
|
}
|
|
340
340
|
/**
|
|
341
341
|
* 初始化资源目录:创建 {ID}/ 文件夹
|
|
@@ -367,8 +367,8 @@ class it {
|
|
|
367
367
|
}
|
|
368
368
|
}
|
|
369
369
|
async saveShard(t, e, s, n) {
|
|
370
|
-
const i = J(s), o = this.shardPath(t, e, i),
|
|
371
|
-
await this.fs.mkdir(
|
|
370
|
+
const i = J(s), o = this.shardPath(t, e, i), r = o.substring(0, o.lastIndexOf("/"));
|
|
371
|
+
await this.fs.mkdir(r), await this.fs.writeFile(o, JSON.stringify(n, null, 2));
|
|
372
372
|
}
|
|
373
373
|
async loadAllShards(t, e) {
|
|
374
374
|
const s = {};
|
|
@@ -383,7 +383,7 @@ class it {
|
|
|
383
383
|
}
|
|
384
384
|
return s;
|
|
385
385
|
}
|
|
386
|
-
for (let n = 0; n <
|
|
386
|
+
for (let n = 0; n < T; n++) {
|
|
387
387
|
const i = this.shardPath(t, e, n);
|
|
388
388
|
try {
|
|
389
389
|
if (await this.fs.exists(i)) {
|
|
@@ -396,37 +396,37 @@ class it {
|
|
|
396
396
|
return s;
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
function W(
|
|
399
|
+
function W(c, t) {
|
|
400
400
|
const e = t.toLowerCase();
|
|
401
401
|
let s = 0;
|
|
402
|
-
const n =
|
|
402
|
+
const n = c.title.toLowerCase();
|
|
403
403
|
n === e ? s = 200 : n.startsWith(e) ? s = 150 : n.includes(e) && (s = 100);
|
|
404
|
-
const i = [...
|
|
404
|
+
const i = [...c.additional_titles || [], ...c.attached_texts || []];
|
|
405
405
|
for (const a of i) {
|
|
406
406
|
const h = a.toLowerCase();
|
|
407
407
|
h === e ? s = Math.max(s, 120) : h.startsWith(e) ? s = Math.max(s, 90) : h.includes(e) && (s = Math.max(s, 60));
|
|
408
408
|
}
|
|
409
409
|
let o = 0;
|
|
410
|
-
if (
|
|
411
|
-
const a =
|
|
410
|
+
if (c.author) {
|
|
411
|
+
const a = c.author.toLowerCase();
|
|
412
412
|
a === e ? o = 80 : a.includes(e) && (o = 50);
|
|
413
413
|
}
|
|
414
|
-
let
|
|
415
|
-
|
|
414
|
+
let r = 0;
|
|
415
|
+
c.dynasty && c.dynasty.toLowerCase().includes(e) && (r = 30);
|
|
416
416
|
let l = s;
|
|
417
|
-
return l === 0 && (l = Math.max(o,
|
|
417
|
+
return l === 0 && (l = Math.max(o, r)), l === 0 ? 0 : (l += Math.max(0, 20 - n.length), c.type === "work" ? l = Math.round(l * 1.05) : c.type === "collection" && (l = Math.round(l * 1.02)), c.has_text && (l += 3), c.has_image && (l += 2), l);
|
|
418
418
|
}
|
|
419
|
-
function wt(
|
|
419
|
+
function wt(c, t) {
|
|
420
420
|
return t === null ? void 0 : t;
|
|
421
421
|
}
|
|
422
|
-
function B(
|
|
423
|
-
const e =
|
|
422
|
+
function B(c, t) {
|
|
423
|
+
const e = c.map((s) => ({ entry: s, score: W(s, t) })).filter((s) => s.score > 0);
|
|
424
424
|
return e.sort((s, n) => n.score !== s.score ? n.score - s.score : s.entry.title.length - n.entry.title.length), e.map((s) => s.entry);
|
|
425
425
|
}
|
|
426
|
-
function O(
|
|
427
|
-
const n =
|
|
426
|
+
function O(c, t, e, s) {
|
|
427
|
+
const n = c.map((i) => {
|
|
428
428
|
const o = W(i, t);
|
|
429
|
-
let
|
|
429
|
+
let r = 0;
|
|
430
430
|
const l = s[i.id];
|
|
431
431
|
if (l && e) {
|
|
432
432
|
const a = {
|
|
@@ -436,14 +436,14 @@ function O(r, t, e, s) {
|
|
|
436
436
|
additional_titles: l.at ?? i.additional_titles,
|
|
437
437
|
attached_texts: l.axt ?? i.attached_texts
|
|
438
438
|
};
|
|
439
|
-
|
|
439
|
+
r = W(a, e);
|
|
440
440
|
}
|
|
441
|
-
return { entry: i, score: Math.max(o,
|
|
441
|
+
return { entry: i, score: Math.max(o, r) };
|
|
442
442
|
}).filter((i) => i.score > 0);
|
|
443
443
|
return n.sort((i, o) => o.score !== i.score ? o.score - i.score : i.entry.title.length - o.entry.title.length), n.map((i) => i.entry);
|
|
444
444
|
}
|
|
445
|
-
function
|
|
446
|
-
const t =
|
|
445
|
+
function bt(c) {
|
|
446
|
+
const t = c.volumes ?? [];
|
|
447
447
|
let e, s;
|
|
448
448
|
if (t.length === 0)
|
|
449
449
|
e = [];
|
|
@@ -454,64 +454,64 @@ function _t(r) {
|
|
|
454
454
|
for (const i of t) {
|
|
455
455
|
const o = i.volume;
|
|
456
456
|
e.push(o);
|
|
457
|
-
const
|
|
457
|
+
const r = {};
|
|
458
458
|
for (const [l, a] of Object.entries(i))
|
|
459
|
-
l === "volume" || l === "status" || l === "file" || typeof a == "string" && (l.includes("url") || l.includes("id")) && (
|
|
459
|
+
l === "volume" || l === "status" || l === "file" || typeof a == "string" && (l.includes("url") || l.includes("id")) && (r[l] = a);
|
|
460
460
|
s.push({
|
|
461
461
|
volume: o,
|
|
462
462
|
status: i.status,
|
|
463
|
-
urls: Object.keys(
|
|
463
|
+
urls: Object.keys(r).length > 0 ? r : void 0,
|
|
464
464
|
file: i.file
|
|
465
465
|
});
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
468
|
const n = {
|
|
469
|
-
title:
|
|
470
|
-
book_id:
|
|
471
|
-
work_id:
|
|
469
|
+
title: c.title ?? "",
|
|
470
|
+
book_id: c.book_id ?? null,
|
|
471
|
+
work_id: c.work_id ?? null,
|
|
472
472
|
volumes: e,
|
|
473
|
-
section:
|
|
474
|
-
sub_items:
|
|
475
|
-
edition:
|
|
476
|
-
expected_volumes:
|
|
477
|
-
found_volumes:
|
|
478
|
-
missing_volumes:
|
|
473
|
+
section: c.section,
|
|
474
|
+
sub_items: c.sub_items,
|
|
475
|
+
edition: c.edition,
|
|
476
|
+
expected_volumes: c.expected_volumes,
|
|
477
|
+
found_volumes: c.found_volumes,
|
|
478
|
+
missing_volumes: c.missing_vols ?? c.missing_volumes
|
|
479
479
|
};
|
|
480
480
|
s && (n.volume_details = s);
|
|
481
481
|
for (const i of Object.keys(n))
|
|
482
482
|
n[i] === void 0 && delete n[i];
|
|
483
483
|
return n;
|
|
484
484
|
}
|
|
485
|
-
function
|
|
485
|
+
function kt(c) {
|
|
486
486
|
const t = {
|
|
487
|
-
total_books:
|
|
487
|
+
total_books: c.total_books ?? 0
|
|
488
488
|
};
|
|
489
|
-
return
|
|
489
|
+
return c.processed_volumes != null && (t.processed_volumes = c.processed_volumes), c.matched_works != null && (t.matched_works = c.matched_works), c.unmatched_works != null && (t.unmatched_works = c.unmatched_works), c.total_found_volumes != null && (t.total_found_volumes = c.total_found_volumes), t;
|
|
490
490
|
}
|
|
491
|
-
function ot(
|
|
491
|
+
function ot(c) {
|
|
492
492
|
var n;
|
|
493
|
-
const t =
|
|
493
|
+
const t = c, e = (t.books ?? []).map(bt), s = {
|
|
494
494
|
collection_id: t.collection_id ?? "",
|
|
495
495
|
title: t.title ?? "",
|
|
496
496
|
total_volumes: t.total_volumes ?? 0,
|
|
497
|
-
stats:
|
|
497
|
+
stats: kt(t.stats ?? {}),
|
|
498
498
|
books: e
|
|
499
499
|
};
|
|
500
500
|
return t.source && (s.source = t.source), t.resource_id && (s.resource_id = t.resource_id), t.resource_name && (s.resource_name = t.resource_name), (n = t.sections) != null && n.length && (s.sections = t.sections), t.volume_index && Object.keys(t.volume_index).length > 0 && (s.volume_index = t.volume_index), s;
|
|
501
501
|
}
|
|
502
|
-
const
|
|
502
|
+
const It = "https://raw.githubusercontent.com", St = [
|
|
503
503
|
"https://fastly.jsdelivr.net/gh",
|
|
504
504
|
"https://cdn.jsdelivr.net/gh"
|
|
505
|
-
],
|
|
506
|
-
class
|
|
505
|
+
], xt = 5e3;
|
|
506
|
+
class Lt {
|
|
507
507
|
// null=未加载, false=不可用
|
|
508
508
|
constructor(t) {
|
|
509
509
|
this.cache = null, this.cacheLoading = null, this.pathMap = /* @__PURE__ */ new Map(), this.searchSCache = null, this.t2sConverter = null, this.config = {
|
|
510
510
|
org: t.org,
|
|
511
511
|
repos: t.repos,
|
|
512
|
-
baseUrl: t.baseUrl ??
|
|
513
|
-
cdnUrls: t.cdnUrls ??
|
|
514
|
-
timeout: t.timeout ??
|
|
512
|
+
baseUrl: t.baseUrl ?? It,
|
|
513
|
+
cdnUrls: t.cdnUrls ?? St,
|
|
514
|
+
timeout: t.timeout ?? xt
|
|
515
515
|
};
|
|
516
516
|
}
|
|
517
517
|
/** 确保 index 数据已加载到缓存 */
|
|
@@ -566,9 +566,9 @@ class Tt {
|
|
|
566
566
|
} catch {
|
|
567
567
|
}
|
|
568
568
|
for (const o of this.config.cdnUrls) {
|
|
569
|
-
const
|
|
569
|
+
const r = `${o}/${this.config.org}/${t}@main/${encodeURI(e)}`;
|
|
570
570
|
try {
|
|
571
|
-
if ((await fetch(
|
|
571
|
+
if ((await fetch(r, {
|
|
572
572
|
method: "HEAD",
|
|
573
573
|
signal: AbortSignal.timeout(this.config.timeout)
|
|
574
574
|
})).ok) return !0;
|
|
@@ -585,9 +585,9 @@ class Tt {
|
|
|
585
585
|
} catch {
|
|
586
586
|
}
|
|
587
587
|
for (const o of this.config.cdnUrls) {
|
|
588
|
-
const
|
|
588
|
+
const r = `${o}/${this.config.org}/${t}@main/${encodeURI(n)}`;
|
|
589
589
|
try {
|
|
590
|
-
if ((await fetch(
|
|
590
|
+
if ((await fetch(r, {
|
|
591
591
|
method: "HEAD",
|
|
592
592
|
signal: AbortSignal.timeout(this.config.timeout)
|
|
593
593
|
})).ok) return !0;
|
|
@@ -609,10 +609,10 @@ class Tt {
|
|
|
609
609
|
}
|
|
610
610
|
const n = [];
|
|
611
611
|
for (const i of ["books", "works"])
|
|
612
|
-
for (let o = 0; o <
|
|
613
|
-
const
|
|
612
|
+
for (let o = 0; o < T; o++) {
|
|
613
|
+
const r = `index/${i}/${o.toString(16)}.json`;
|
|
614
614
|
n.push(
|
|
615
|
-
this.fetchFileWithFallback(t,
|
|
615
|
+
this.fetchFileWithFallback(t, r).then((l) => {
|
|
616
616
|
Object.assign(s[i], l);
|
|
617
617
|
}).catch(() => {
|
|
618
618
|
})
|
|
@@ -639,8 +639,8 @@ class Tt {
|
|
|
639
639
|
["works", "work"],
|
|
640
640
|
["entities", "entity"]
|
|
641
641
|
];
|
|
642
|
-
for (const [
|
|
643
|
-
const a = t[
|
|
642
|
+
for (const [r, l] of n) {
|
|
643
|
+
const a = t[r];
|
|
644
644
|
if (a)
|
|
645
645
|
for (const h of Object.values(a)) {
|
|
646
646
|
const u = h, d = l === "entity" ? u.primary_name || h.title || h.name || h.id : h.title || h.name || h.id;
|
|
@@ -689,20 +689,20 @@ class Tt {
|
|
|
689
689
|
}
|
|
690
690
|
const t = await this.ensureLoaded(), e = this.t2sConverter, s = {};
|
|
691
691
|
for (const o of t) {
|
|
692
|
-
const
|
|
693
|
-
if (l !== o.title && (
|
|
692
|
+
const r = {}, l = e(o.title);
|
|
693
|
+
if (l !== o.title && (r.t = l), o.author) {
|
|
694
694
|
const a = e(o.author);
|
|
695
|
-
a !== o.author && (
|
|
695
|
+
a !== o.author && (r.a = a);
|
|
696
696
|
}
|
|
697
697
|
if ((n = o.additional_titles) != null && n.length) {
|
|
698
698
|
const a = o.additional_titles.map(e);
|
|
699
|
-
a.some((h, u) => h !== o.additional_titles[u]) && (
|
|
699
|
+
a.some((h, u) => h !== o.additional_titles[u]) && (r.at = a);
|
|
700
700
|
}
|
|
701
701
|
if ((i = o.attached_texts) != null && i.length) {
|
|
702
702
|
const a = o.attached_texts.map(e);
|
|
703
|
-
a.some((h, u) => h !== o.attached_texts[u]) && (
|
|
703
|
+
a.some((h, u) => h !== o.attached_texts[u]) && (r.axt = a);
|
|
704
704
|
}
|
|
705
|
-
Object.keys(
|
|
705
|
+
Object.keys(r).length > 0 && (s[o.id] = r);
|
|
706
706
|
}
|
|
707
707
|
return this.searchSCache = s, { searchS: s, converter: e };
|
|
708
708
|
}
|
|
@@ -714,16 +714,16 @@ class Tt {
|
|
|
714
714
|
const f = String(u[i] ?? ""), p = String(d[i] ?? ""), k = f.localeCompare(p, "zh");
|
|
715
715
|
return o === "asc" ? k : -k;
|
|
716
716
|
});
|
|
717
|
-
const
|
|
717
|
+
const r = e.page || 1, l = e.pageSize || 50, a = (r - 1) * l;
|
|
718
718
|
return {
|
|
719
719
|
entries: n.slice(a, a + l),
|
|
720
720
|
total: n.length,
|
|
721
|
-
page:
|
|
721
|
+
page: r,
|
|
722
722
|
pageSize: l
|
|
723
723
|
};
|
|
724
724
|
}
|
|
725
725
|
async search(t, e, s) {
|
|
726
|
-
const n = await this.ensureLoaded(), { searchS: i, converter: o } = await this.ensureSearchSBuilt(),
|
|
726
|
+
const n = await this.ensureLoaded(), { searchS: i, converter: o } = await this.ensureSearchSBuilt(), r = n.filter((p) => p.type === e), l = o ? o(t) : void 0, h = Object.keys(i).length > 0 ? O(r, t, l, i) : B(r, t), u = s.page || 1, d = s.pageSize || 50, f = (u - 1) * d;
|
|
727
727
|
return {
|
|
728
728
|
entries: h.slice(f, f + d),
|
|
729
729
|
total: h.length,
|
|
@@ -732,9 +732,9 @@ class Tt {
|
|
|
732
732
|
};
|
|
733
733
|
}
|
|
734
734
|
async searchAll(t, e = 5) {
|
|
735
|
-
const s = await this.ensureLoaded(), { searchS: n, converter: i } = await this.ensureSearchSBuilt(), o = ["work", "book", "collection"],
|
|
735
|
+
const s = await this.ensureLoaded(), { searchS: n, converter: i } = await this.ensureSearchSBuilt(), o = ["work", "book", "collection"], r = i ? i(t) : void 0, l = Object.keys(n).length > 0, a = o.map((h) => {
|
|
736
736
|
const u = s.filter((d) => d.type === h);
|
|
737
|
-
return l ? O(u, t,
|
|
737
|
+
return l ? O(u, t, r, n) : B(u, t);
|
|
738
738
|
});
|
|
739
739
|
return {
|
|
740
740
|
works: a[0].slice(0, e),
|
|
@@ -751,7 +751,7 @@ class Tt {
|
|
|
751
751
|
if (s) {
|
|
752
752
|
const i = s.isDraft ? this.config.repos.draft : this.config.repos.official;
|
|
753
753
|
if (n = await this.fetchItemByPath(i, s.path), n) {
|
|
754
|
-
const o = e.find((
|
|
754
|
+
const o = e.find((r) => r.id === t);
|
|
755
755
|
o != null && o.has_collated && (n.has_collated = !0);
|
|
756
756
|
}
|
|
757
757
|
} else
|
|
@@ -810,7 +810,7 @@ class Tt {
|
|
|
810
810
|
} catch {
|
|
811
811
|
return null;
|
|
812
812
|
}
|
|
813
|
-
const i = n === "draft" ? this.config.repos.draft : this.config.repos.official, o = e[s],
|
|
813
|
+
const i = n === "draft" ? this.config.repos.draft : this.config.repos.official, o = e[s], r = t.padEnd(3, "_").substring(0, 3), l = `${o}/${r[0]}/${r[1]}/${r[2]}`, a = `https://api.github.com/repos/${this.config.org}/${i}/contents/${l}`;
|
|
814
814
|
try {
|
|
815
815
|
const h = await fetch(a, {
|
|
816
816
|
signal: AbortSignal.timeout(this.config.timeout)
|
|
@@ -833,9 +833,9 @@ class Tt {
|
|
|
833
833
|
const a = o[0];
|
|
834
834
|
i = typeof a == "object" && a !== null ? a.name || "" : String(a);
|
|
835
835
|
}
|
|
836
|
-
let
|
|
836
|
+
let r = !0;
|
|
837
837
|
try {
|
|
838
|
-
|
|
838
|
+
r = $(x(t)).status === "draft";
|
|
839
839
|
} catch {
|
|
840
840
|
}
|
|
841
841
|
const l = this.pathMap.get(t);
|
|
@@ -843,7 +843,7 @@ class Tt {
|
|
|
843
843
|
id: t,
|
|
844
844
|
title: e.title || e.书名 || t,
|
|
845
845
|
type: n,
|
|
846
|
-
isDraft:
|
|
846
|
+
isDraft: r,
|
|
847
847
|
author: i,
|
|
848
848
|
dynasty: e.dynasty,
|
|
849
849
|
role: e.role,
|
|
@@ -887,7 +887,7 @@ class Tt {
|
|
|
887
887
|
if (n.length === 0) return null;
|
|
888
888
|
const i = [];
|
|
889
889
|
for (const o of n) {
|
|
890
|
-
const
|
|
890
|
+
const r = `${e.dir}/${t}/${o.id}/volume_book_mapping.json`, l = await this.fetchFile(e.repo, r);
|
|
891
891
|
l && i.push({
|
|
892
892
|
resource_id: o.id,
|
|
893
893
|
short_name: o.short_name,
|
|
@@ -950,7 +950,7 @@ class at {
|
|
|
950
950
|
throw new Error("Clock moved backwards. Refusing to generate ID.");
|
|
951
951
|
s === this.lastTimestamp && t === this.lastStatus ? (this.sequence = this.sequence + 1 & G, this.sequence === 0 && (s = this._tilNextUnit(this.lastTimestamp, t))) : this.sequence = 0, this.lastTimestamp = s, this.lastStatus = t;
|
|
952
952
|
const n = z(t, e, BigInt(s), this.machineId, this.sequence);
|
|
953
|
-
return
|
|
953
|
+
return D(n);
|
|
954
954
|
}
|
|
955
955
|
/**
|
|
956
956
|
* 生成下一个 ID(返回 bigint 原始值)
|
|
@@ -1036,8 +1036,8 @@ class Bt {
|
|
|
1036
1036
|
if (e.contained_in && Array.isArray(e.contained_in) && e.contained_in.length > 0) {
|
|
1037
1037
|
const i = e.contained_in[0], o = typeof i == "string" ? i : i.id;
|
|
1038
1038
|
if (o) {
|
|
1039
|
-
const
|
|
1040
|
-
|
|
1039
|
+
const r = await this.resolveEntity(o);
|
|
1040
|
+
r && (s.belongsToCollection = { ...r, type: "collection" });
|
|
1041
1041
|
}
|
|
1042
1042
|
}
|
|
1043
1043
|
} else if (n === "collection") {
|
|
@@ -1133,13 +1133,13 @@ class Bt {
|
|
|
1133
1133
|
const s = e && e !== "all" ? [e] : ["book", "collection", "work"], n = [];
|
|
1134
1134
|
for (const i of s) {
|
|
1135
1135
|
const o = await this.storage.searchEntries(t, i);
|
|
1136
|
-
for (const
|
|
1136
|
+
for (const r of o)
|
|
1137
1137
|
n.push({
|
|
1138
|
-
id:
|
|
1139
|
-
title:
|
|
1140
|
-
type:
|
|
1141
|
-
author:
|
|
1142
|
-
dynasty:
|
|
1138
|
+
id: r.id,
|
|
1139
|
+
title: r.title,
|
|
1140
|
+
type: r.type,
|
|
1141
|
+
author: r.author,
|
|
1142
|
+
dynasty: r.dynasty
|
|
1143
1143
|
});
|
|
1144
1144
|
}
|
|
1145
1145
|
return n;
|
|
@@ -1235,10 +1235,10 @@ class Bt {
|
|
|
1235
1235
|
return { entries: t.slice(o, o + n), total: i, page: s, pageSize: n };
|
|
1236
1236
|
}
|
|
1237
1237
|
}
|
|
1238
|
-
const
|
|
1238
|
+
const vt = "/data", Ct = 1e4;
|
|
1239
1239
|
class Ft {
|
|
1240
1240
|
constructor(t = {}) {
|
|
1241
|
-
this.indexCache = null, this.indexLoading = null, this.pathMap = /* @__PURE__ */ new Map(), this.chunkCache = /* @__PURE__ */ new Map(), this.chunkLoading = /* @__PURE__ */ new Map(), this.manifest = null, this.manifestLoading = null, this.tiyaoCache = /* @__PURE__ */ new Map(), this.tiyaoLoading = /* @__PURE__ */ new Map(), this.searchSCache = null, this.searchSLoading = null, this.searchSLoaded = !1, this.metaCache = null, this.metaLoading = null, this.metaTried = !1, this.t2sConverter = null, this.t2sLoading = null, this.version = void 0, this.versionPromise = null, this.basePath = t.basePath ??
|
|
1241
|
+
this.indexCache = null, this.indexLoading = null, this.pathMap = /* @__PURE__ */ new Map(), this.chunkCache = /* @__PURE__ */ new Map(), this.chunkLoading = /* @__PURE__ */ new Map(), this.manifest = null, this.manifestLoading = null, this.tiyaoCache = /* @__PURE__ */ new Map(), this.tiyaoLoading = /* @__PURE__ */ new Map(), this.searchSCache = null, this.searchSLoading = null, this.searchSLoaded = !1, this.metaCache = null, this.metaLoading = null, this.metaTried = !1, this.t2sConverter = null, this.t2sLoading = null, this.version = void 0, this.versionPromise = null, this.basePath = t.basePath ?? vt, this.timeout = t.timeout ?? Ct;
|
|
1242
1242
|
}
|
|
1243
1243
|
// ─── 内部工具 ───
|
|
1244
1244
|
/**
|
|
@@ -1282,15 +1282,15 @@ class Ft {
|
|
|
1282
1282
|
["works", "work"],
|
|
1283
1283
|
["entities", "entity"]
|
|
1284
1284
|
];
|
|
1285
|
-
for (const [o,
|
|
1285
|
+
for (const [o, r] of s) {
|
|
1286
1286
|
const l = t[o];
|
|
1287
1287
|
if (l)
|
|
1288
1288
|
for (const a of Object.values(l)) {
|
|
1289
|
-
const h =
|
|
1289
|
+
const h = r === "entity" ? a.primary_name || a.title || a.name || a.id : a.title || a.name || a.id;
|
|
1290
1290
|
e.push({
|
|
1291
1291
|
id: a.id,
|
|
1292
1292
|
title: h,
|
|
1293
|
-
type:
|
|
1293
|
+
type: r,
|
|
1294
1294
|
isDraft: !0,
|
|
1295
1295
|
// bundle 目前只打包 draft 数据
|
|
1296
1296
|
author: a.author,
|
|
@@ -1426,11 +1426,11 @@ class Ft {
|
|
|
1426
1426
|
if (this.tiyaoCache.has(s)) return this.tiyaoCache.get(s);
|
|
1427
1427
|
const n = this.tiyaoLoading.get(s);
|
|
1428
1428
|
if (n) return n;
|
|
1429
|
-
const i = (
|
|
1430
|
-
const
|
|
1429
|
+
const i = (r) => String(r).padStart(3, "0"), o = (async () => {
|
|
1430
|
+
const r = await this.fetchJson(
|
|
1431
1431
|
`${this.basePath}/tiyao/juan-${i(t)}-${i(e)}.json`
|
|
1432
1432
|
);
|
|
1433
|
-
return this.tiyaoCache.set(s,
|
|
1433
|
+
return this.tiyaoCache.set(s, r), r;
|
|
1434
1434
|
})();
|
|
1435
1435
|
this.tiyaoLoading.set(s, o);
|
|
1436
1436
|
try {
|
|
@@ -1467,16 +1467,16 @@ class Ft {
|
|
|
1467
1467
|
}
|
|
1468
1468
|
}
|
|
1469
1469
|
const t = await this.ensureLoaded();
|
|
1470
|
-
let e = 0, s = 0, n = 0, i = 0, o = 0,
|
|
1470
|
+
let e = 0, s = 0, n = 0, i = 0, o = 0, r = 0;
|
|
1471
1471
|
const l = {};
|
|
1472
1472
|
for (const h of t)
|
|
1473
|
-
h.type === "work" ? (e++, h.has_text && o++, h.has_image &&
|
|
1473
|
+
h.type === "work" ? (e++, h.has_text && o++, h.has_image && r++, h.subtype && (l[h.subtype] = (l[h.subtype] ?? 0) + 1)) : h.type === "book" ? s++ : h.type === "collection" ? n++ : h.type === "entity" && i++;
|
|
1474
1474
|
const a = {
|
|
1475
1475
|
works: e,
|
|
1476
1476
|
books: s,
|
|
1477
1477
|
collections: n,
|
|
1478
1478
|
entities: i,
|
|
1479
|
-
resourceCounts: { hasText: o, hasImage:
|
|
1479
|
+
resourceCounts: { hasText: o, hasImage: r },
|
|
1480
1480
|
subtypeStats: l
|
|
1481
1481
|
};
|
|
1482
1482
|
return this.metaCache = a, a;
|
|
@@ -1494,16 +1494,16 @@ class Ft {
|
|
|
1494
1494
|
const d = String(h[i] ?? ""), f = String(u[i] ?? ""), p = d.localeCompare(f, "zh");
|
|
1495
1495
|
return o === "asc" ? p : -p;
|
|
1496
1496
|
});
|
|
1497
|
-
const
|
|
1497
|
+
const r = e.page || 1, l = e.pageSize || 50, a = (r - 1) * l;
|
|
1498
1498
|
return {
|
|
1499
1499
|
entries: n.slice(a, a + l),
|
|
1500
1500
|
total: n.length,
|
|
1501
|
-
page:
|
|
1501
|
+
page: r,
|
|
1502
1502
|
pageSize: l
|
|
1503
1503
|
};
|
|
1504
1504
|
}
|
|
1505
1505
|
async search(t, e, s) {
|
|
1506
|
-
const n = await this.ensureLoaded(), i = await this.ensureSearchSLoaded(), o = await this.ensureT2S(),
|
|
1506
|
+
const n = await this.ensureLoaded(), i = await this.ensureSearchSLoaded(), o = await this.ensureT2S(), r = n.filter((p) => p.type === e), l = o ? o(t) : void 0, h = Object.keys(i).length > 0 ? O(r, t, l, i) : B(r, t), u = s.page || 1, d = s.pageSize || 50, f = (u - 1) * d;
|
|
1507
1507
|
return {
|
|
1508
1508
|
entries: h.slice(f, f + d),
|
|
1509
1509
|
total: h.length,
|
|
@@ -1512,9 +1512,9 @@ class Ft {
|
|
|
1512
1512
|
};
|
|
1513
1513
|
}
|
|
1514
1514
|
async searchAll(t, e = 5) {
|
|
1515
|
-
const s = await this.ensureLoaded(), n = await this.ensureSearchSLoaded(), i = await this.ensureT2S(), o = ["work", "book", "collection", "entity"],
|
|
1515
|
+
const s = await this.ensureLoaded(), n = await this.ensureSearchSLoaded(), i = await this.ensureT2S(), o = ["work", "book", "collection", "entity"], r = i ? i(t) : void 0, l = Object.keys(n).length > 0, a = o.map((h) => {
|
|
1516
1516
|
const u = s.filter((d) => d.type === h);
|
|
1517
|
-
return l ? O(u, t,
|
|
1517
|
+
return l ? O(u, t, r, n) : B(u, t);
|
|
1518
1518
|
});
|
|
1519
1519
|
return {
|
|
1520
1520
|
works: a[0].slice(0, e),
|
|
@@ -1530,17 +1530,46 @@ class Ft {
|
|
|
1530
1530
|
async getItem(t) {
|
|
1531
1531
|
try {
|
|
1532
1532
|
const s = (await this.loadChunkForId(t))[t] || null;
|
|
1533
|
-
|
|
1534
|
-
const n = (await this.ensureLoaded()).find((i) => i.id === t);
|
|
1535
|
-
n != null && n.has_collated && (s.has_collated = !0), s.type === "entity" && !s.title && s.primary_name && (s.title = s.primary_name);
|
|
1536
|
-
}
|
|
1537
|
-
return s;
|
|
1533
|
+
return s && s.type === "entity" && !s.title && s.primary_name && (s.title = s.primary_name), s;
|
|
1538
1534
|
} catch {
|
|
1539
1535
|
return null;
|
|
1540
1536
|
}
|
|
1541
1537
|
}
|
|
1538
|
+
/**
|
|
1539
|
+
* 优先用 chunk 构造 IndexEntry,避免触发 ensureLoaded() 拉全量 index.json。
|
|
1540
|
+
* 旧 bundle 没有把 has_collated 等字段注入 chunk 时回退到 ensureLoaded。
|
|
1541
|
+
*/
|
|
1542
1542
|
async getEntry(t) {
|
|
1543
|
-
|
|
1543
|
+
var s, n;
|
|
1544
|
+
try {
|
|
1545
|
+
const o = (await this.loadChunkForId(t))[t];
|
|
1546
|
+
if (o) {
|
|
1547
|
+
const r = pt(t), l = r === "entity" ? o.primary_name || o.title || o.name || t : o.title || o.name || t;
|
|
1548
|
+
return {
|
|
1549
|
+
id: t,
|
|
1550
|
+
title: l,
|
|
1551
|
+
type: r,
|
|
1552
|
+
isDraft: !0,
|
|
1553
|
+
author: o.author,
|
|
1554
|
+
dynasty: o.dynasty,
|
|
1555
|
+
role: o.role,
|
|
1556
|
+
additional_titles: (s = o.additional_titles) == null ? void 0 : s.map((a) => typeof a == "string" ? a : a == null ? void 0 : a.book_title).filter(Boolean),
|
|
1557
|
+
attached_texts: (n = o.attached_texts) == null ? void 0 : n.map((a) => typeof a == "string" ? a : a == null ? void 0 : a.book_title).filter(Boolean),
|
|
1558
|
+
edition: o.edition,
|
|
1559
|
+
juan_count: o.juan_count,
|
|
1560
|
+
has_text: o.has_text,
|
|
1561
|
+
has_image: o.has_image,
|
|
1562
|
+
has_collated: o.has_collated,
|
|
1563
|
+
subtype: o.subtype,
|
|
1564
|
+
primary_name: o.primary_name,
|
|
1565
|
+
birth_year: o.birth_year,
|
|
1566
|
+
death_year: o.death_year,
|
|
1567
|
+
cbdb_id: o.cbdb_id
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
} catch {
|
|
1571
|
+
}
|
|
1572
|
+
return (await this.ensureLoaded()).find((i) => i.id === t) || null;
|
|
1544
1573
|
}
|
|
1545
1574
|
async getAllEntries() {
|
|
1546
1575
|
return this.ensureLoaded();
|
|
@@ -1605,8 +1634,8 @@ class Ft {
|
|
|
1605
1634
|
if (e.includes("..") || !e.endsWith(".json")) return null;
|
|
1606
1635
|
const s = e.replace(/\.json$/, ".md"), n = await this.ensureVersion(), i = `${this.basePath}/items/${t}/collated_edition/text/${s}`, o = n ? `${i}?v=${n}` : i;
|
|
1607
1636
|
try {
|
|
1608
|
-
const
|
|
1609
|
-
return
|
|
1637
|
+
const r = await fetch(o);
|
|
1638
|
+
return r.ok ? await r.text() : null;
|
|
1610
1639
|
} catch {
|
|
1611
1640
|
return null;
|
|
1612
1641
|
}
|
|
@@ -1672,12 +1701,12 @@ class Ot extends F {
|
|
|
1672
1701
|
super(t), this.name = "ConfigError";
|
|
1673
1702
|
}
|
|
1674
1703
|
}
|
|
1675
|
-
class
|
|
1704
|
+
class Dt extends F {
|
|
1676
1705
|
constructor(t) {
|
|
1677
1706
|
super(t), this.name = "MigrationError";
|
|
1678
1707
|
}
|
|
1679
1708
|
}
|
|
1680
|
-
class
|
|
1709
|
+
class Ut {
|
|
1681
1710
|
constructor(t, e, s = 1) {
|
|
1682
1711
|
this.storage = new it(t, e), this.idGen = new at(s);
|
|
1683
1712
|
}
|
|
@@ -1687,7 +1716,7 @@ class Dt {
|
|
|
1687
1716
|
}
|
|
1688
1717
|
/** Encode a bigint ID to Base36 string. */
|
|
1689
1718
|
encodeId(t) {
|
|
1690
|
-
return
|
|
1719
|
+
return D(t);
|
|
1691
1720
|
}
|
|
1692
1721
|
/** Decode an ID string to bigint (supports base36 and legacy base58). */
|
|
1693
1722
|
decodeId(t) {
|
|
@@ -1698,7 +1727,7 @@ class Dt {
|
|
|
1698
1727
|
let n = t.id || t.ID;
|
|
1699
1728
|
if (n)
|
|
1700
1729
|
try {
|
|
1701
|
-
const o =
|
|
1730
|
+
const o = L(n);
|
|
1702
1731
|
e || (e = o.type);
|
|
1703
1732
|
} catch {
|
|
1704
1733
|
throw new F(`Invalid ID format: ${n}`);
|
|
@@ -1726,14 +1755,14 @@ class Dt {
|
|
|
1726
1755
|
资源: "resources",
|
|
1727
1756
|
收藏历史: "history",
|
|
1728
1757
|
其他版本: "related_books"
|
|
1729
|
-
},
|
|
1730
|
-
if (
|
|
1731
|
-
if (
|
|
1732
|
-
const a = i[
|
|
1733
|
-
i[
|
|
1758
|
+
}, r = e in o ? o[e] : e;
|
|
1759
|
+
if (r === null) return !1;
|
|
1760
|
+
if (r === "description" && typeof s == "string") {
|
|
1761
|
+
const a = i[r] || {};
|
|
1762
|
+
i[r] = { text: s, sources: a.sources || [] };
|
|
1734
1763
|
} else
|
|
1735
|
-
i[
|
|
1736
|
-
const l =
|
|
1764
|
+
i[r] = s;
|
|
1765
|
+
const l = L(t);
|
|
1737
1766
|
return await this.storage.saveItem(l.type, t, i), !0;
|
|
1738
1767
|
} catch {
|
|
1739
1768
|
return !1;
|
|
@@ -1765,7 +1794,7 @@ class Dt {
|
|
|
1765
1794
|
return this.storage;
|
|
1766
1795
|
}
|
|
1767
1796
|
}
|
|
1768
|
-
const
|
|
1797
|
+
const Et = {
|
|
1769
1798
|
wikisource: "wikisource",
|
|
1770
1799
|
shidianguji: "shidianguji",
|
|
1771
1800
|
archive: "archive",
|
|
@@ -1775,16 +1804,16 @@ const Ct = {
|
|
|
1775
1804
|
"db.sido": "sido",
|
|
1776
1805
|
"guji.artx": "guji-artx",
|
|
1777
1806
|
"digital.library": "digital-library"
|
|
1778
|
-
}, q = /* @__PURE__ */ new Set(["text", "image", "text+image", "physical"]), Y = /* @__PURE__ */ new Set(["text", "image", "physical"]),
|
|
1779
|
-
function Nt(
|
|
1780
|
-
if (!
|
|
1807
|
+
}, q = /* @__PURE__ */ new Set(["text", "image", "text+image", "physical"]), Y = /* @__PURE__ */ new Set(["text", "image", "physical"]), $t = /* @__PURE__ */ new Set(["catalog", "search"]), At = /* @__PURE__ */ new Set(["com", "org", "net", "cn", "edu", "gov", "io", "jp", "tw", "hk"]);
|
|
1808
|
+
function Nt(c) {
|
|
1809
|
+
if (!c) return "";
|
|
1781
1810
|
try {
|
|
1782
|
-
const e = new URL(
|
|
1783
|
-
for (const [n, i] of Object.entries(
|
|
1811
|
+
const e = new URL(c).hostname;
|
|
1812
|
+
for (const [n, i] of Object.entries(Et))
|
|
1784
1813
|
if (e.includes(n)) return i;
|
|
1785
1814
|
const s = e.split(".");
|
|
1786
1815
|
if (s.length >= 2) {
|
|
1787
|
-
const n = s.filter((i) =>
|
|
1816
|
+
const n = s.filter((i) => !At.has(i) && i.length > 2);
|
|
1788
1817
|
return n.length > 0 ? n[n.length - 1] : s[s.length - 2];
|
|
1789
1818
|
}
|
|
1790
1819
|
return e;
|
|
@@ -1792,35 +1821,35 @@ function Nt(r) {
|
|
|
1792
1821
|
return "";
|
|
1793
1822
|
}
|
|
1794
1823
|
}
|
|
1795
|
-
function Jt(
|
|
1824
|
+
function Jt(c) {
|
|
1796
1825
|
const t = [];
|
|
1797
|
-
|
|
1826
|
+
c.name || t.push("name is required");
|
|
1798
1827
|
let e = !1;
|
|
1799
|
-
if (
|
|
1800
|
-
if (!Array.isArray(
|
|
1828
|
+
if (c.types !== void 0)
|
|
1829
|
+
if (!Array.isArray(c.types) || c.types.length === 0)
|
|
1801
1830
|
t.push("types must be a non-empty array when present");
|
|
1802
1831
|
else {
|
|
1803
|
-
for (const s of
|
|
1832
|
+
for (const s of c.types)
|
|
1804
1833
|
Y.has(s) || t.push(`invalid types atom '${s}', must be one of ${[...Y].join(", ")}`);
|
|
1805
|
-
e =
|
|
1834
|
+
e = c.types.length === 1 && c.types[0] === "physical";
|
|
1806
1835
|
}
|
|
1807
|
-
else
|
|
1808
|
-
return
|
|
1836
|
+
else c.type !== void 0 ? (q.has(c.type) || t.push(`invalid type '${c.type}', must be one of ${[...q].join(", ")}`), e = c.type === "physical") : t.push("either type or types is required");
|
|
1837
|
+
return c.root_type && !$t.has(c.root_type) && t.push(`invalid root_type '${c.root_type}'`), !e && !c.url && t.push("url is required for non-physical resources"), t;
|
|
1809
1838
|
}
|
|
1810
|
-
const
|
|
1839
|
+
const w = class w {
|
|
1811
1840
|
constructor(t, e = "") {
|
|
1812
1841
|
if (this._type = null, this.title = e, typeof t == "string") {
|
|
1813
|
-
t.startsWith(
|
|
1842
|
+
t.startsWith(w.PREFIX) && (t = t.slice(w.PREFIX.length)), this.idStr = t;
|
|
1814
1843
|
try {
|
|
1815
1844
|
this.idInt = x(t);
|
|
1816
1845
|
} catch {
|
|
1817
1846
|
this.idInt = 0n;
|
|
1818
1847
|
}
|
|
1819
1848
|
} else
|
|
1820
|
-
this.idInt = t, this.idStr =
|
|
1849
|
+
this.idInt = t, this.idStr = D(t);
|
|
1821
1850
|
if (this.idInt > 0n)
|
|
1822
1851
|
try {
|
|
1823
|
-
const s =
|
|
1852
|
+
const s = L(this.idStr);
|
|
1824
1853
|
this._type = s.type;
|
|
1825
1854
|
} catch {
|
|
1826
1855
|
}
|
|
@@ -1832,47 +1861,47 @@ const _ = class _ {
|
|
|
1832
1861
|
return this._type === null ? "" : this._type === "book" ? "📖 " : this._type === "collection" ? "📚 " : this._type === "work" ? "📜 " : "";
|
|
1833
1862
|
}
|
|
1834
1863
|
render(t = !1) {
|
|
1835
|
-
return `[${t ? this.getIcon() : ""}${this.title}](${
|
|
1864
|
+
return `[${t ? this.getIcon() : ""}${this.title}](${w.PREFIX}${this.idStr})`;
|
|
1836
1865
|
}
|
|
1837
1866
|
static parseFromLink(t) {
|
|
1838
1867
|
const e = t.match(/\[(.*?)\]\((.*?)\)/);
|
|
1839
1868
|
if (e) {
|
|
1840
1869
|
const s = e[1], n = e[2];
|
|
1841
|
-
if (n.startsWith(
|
|
1842
|
-
const i = n.slice(
|
|
1843
|
-
return new
|
|
1870
|
+
if (n.startsWith(w.PREFIX)) {
|
|
1871
|
+
const i = n.slice(w.PREFIX.length);
|
|
1872
|
+
return new w(i, s);
|
|
1844
1873
|
}
|
|
1845
1874
|
}
|
|
1846
1875
|
return null;
|
|
1847
1876
|
}
|
|
1848
1877
|
static isBidLink(t) {
|
|
1849
|
-
return t.startsWith(
|
|
1878
|
+
return t.startsWith(w.PREFIX);
|
|
1850
1879
|
}
|
|
1851
1880
|
};
|
|
1852
|
-
|
|
1853
|
-
let K =
|
|
1881
|
+
w.PROTOCOL = "bid:\\\\", w.PREFIX = "bid:\\\\";
|
|
1882
|
+
let K = w;
|
|
1854
1883
|
export {
|
|
1855
1884
|
K as B,
|
|
1856
1885
|
Ot as C,
|
|
1857
|
-
|
|
1886
|
+
Lt as G,
|
|
1858
1887
|
Rt as I,
|
|
1859
1888
|
Bt as L,
|
|
1860
|
-
|
|
1889
|
+
Dt as M,
|
|
1861
1890
|
Mt as S,
|
|
1862
|
-
|
|
1891
|
+
pt as a,
|
|
1863
1892
|
F as b,
|
|
1864
|
-
|
|
1893
|
+
Ut as c,
|
|
1865
1894
|
it as d,
|
|
1866
|
-
|
|
1895
|
+
Tt as e,
|
|
1867
1896
|
Ft as f,
|
|
1868
1897
|
at as g,
|
|
1869
1898
|
st as h,
|
|
1870
|
-
|
|
1899
|
+
D as i,
|
|
1871
1900
|
gt as j,
|
|
1872
1901
|
z as k,
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1902
|
+
Pt as l,
|
|
1903
|
+
L as m,
|
|
1904
|
+
jt as n,
|
|
1876
1905
|
Nt as o,
|
|
1877
1906
|
ot as p,
|
|
1878
1907
|
$ as q,
|