@the_library/public 1.0.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 +2298 -0
- package/assets/branding/data-pond.png +0 -0
- package/assets/branding/dsafe-logo.png +0 -0
- package/assets/branding/founder-photo.jpg +0 -0
- package/assets/branding/icon_transparent.png +0 -0
- package/assets/branding/library-favicon.png +0 -0
- package/assets/branding/pond-enterprise-logo.jpg +0 -0
- package/assets/branding/pond-enterprise-logo.svg +27 -0
- package/dist/branding/index.d.ts +48 -0
- package/dist/branding/index.js +67 -0
- package/dist/branding/index.js.map +1 -0
- package/dist/chunk-2HFOWE5R.js +296 -0
- package/dist/chunk-2HFOWE5R.js.map +1 -0
- package/dist/chunk-3L6LH2XK.js +465 -0
- package/dist/chunk-3L6LH2XK.js.map +1 -0
- package/dist/chunk-4CWVFPBN.js +28 -0
- package/dist/chunk-4CWVFPBN.js.map +1 -0
- package/dist/chunk-AGHPATVL.js +65 -0
- package/dist/chunk-AGHPATVL.js.map +1 -0
- package/dist/chunk-JDUYLUDJ.js +4835 -0
- package/dist/chunk-JDUYLUDJ.js.map +1 -0
- package/dist/chunk-OEZK7IX7.js +77 -0
- package/dist/chunk-OEZK7IX7.js.map +1 -0
- package/dist/chunk-PUYDAUCI.js +2873 -0
- package/dist/chunk-PUYDAUCI.js.map +1 -0
- package/dist/chunk-WHWMTS7D.js +99 -0
- package/dist/chunk-WHWMTS7D.js.map +1 -0
- package/dist/chunk-Y7RS6RTM.js +342 -0
- package/dist/chunk-Y7RS6RTM.js.map +1 -0
- package/dist/chunk-ZEZGI2TP.js +197 -0
- package/dist/chunk-ZEZGI2TP.js.map +1 -0
- package/dist/core-dao-core-logo-VDT2I5IW.svg +33 -0
- package/dist/downloader/dl2-sw.js +199 -0
- package/dist/downloader/dl2-sw.js.map +1 -0
- package/dist/downloader/file-worker-v2.js +258 -0
- package/dist/downloader/file-worker-v2.js.map +1 -0
- package/dist/downloader/index.d.ts +45 -0
- package/dist/downloader/index.js +538 -0
- package/dist/downloader/index.js.map +1 -0
- package/dist/downloader/mu-worker-v2.js +197 -0
- package/dist/downloader/mu-worker-v2.js.map +1 -0
- package/dist/downloader/react.d.ts +19 -0
- package/dist/downloader/react.js +32 -0
- package/dist/downloader/react.js.map +1 -0
- package/dist/downloader/solid.d.ts +21 -0
- package/dist/downloader/solid.js +19 -0
- package/dist/downloader/solid.js.map +1 -0
- package/dist/downloader/sw.d.ts +22 -0
- package/dist/downloader/sw.js +119 -0
- package/dist/downloader/sw.js.map +1 -0
- package/dist/downloader/vue.d.ts +23 -0
- package/dist/downloader/vue.js +19 -0
- package/dist/downloader/vue.js.map +1 -0
- package/dist/level-state-J3pj64Tr.d.ts +15 -0
- package/dist/models/astro.d.ts +47 -0
- package/dist/models/astro.js +44 -0
- package/dist/models/astro.js.map +1 -0
- package/dist/models/index.d.ts +244 -0
- package/dist/models/index.js +340 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/models.d.ts +524 -0
- package/dist/models/models.js +46 -0
- package/dist/models/models.js.map +1 -0
- package/dist/models/models_v2.global.js +1 -0
- package/dist/models/patch-worker.js +543 -0
- package/dist/models/patch-worker.js.map +1 -0
- package/dist/models/react.d.ts +43 -0
- package/dist/models/react.js +73 -0
- package/dist/models/react.js.map +1 -0
- package/dist/models/solid.d.ts +73 -0
- package/dist/models/solid.js +95 -0
- package/dist/models/solid.js.map +1 -0
- package/dist/models/vue.d.ts +51 -0
- package/dist/models/vue.js +98 -0
- package/dist/models/vue.js.map +1 -0
- package/dist/orm-BvkX0aBT.d.ts +507 -0
- package/dist/session-vqOnyxga.d.ts +184 -0
- package/dist/state-BTsp-E4v.d.ts +111 -0
- package/dist/types-Dn0EFMO_.d.ts +293 -0
- package/dist/types-Xb8Ta9tZ.d.ts +155 -0
- package/dist/web3/index.d.ts +820 -0
- package/dist/web3/index.js +1020 -0
- package/dist/web3/index.js.map +1 -0
- package/dist/web3/registry.d.ts +145 -0
- package/dist/web3/registry.js +23 -0
- package/dist/web3/registry.js.map +1 -0
- package/dist/web3/vue.d.ts +174 -0
- package/dist/web3/vue.js +391 -0
- package/dist/web3/vue.js.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1,4835 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bulkAddPatches,
|
|
3
|
+
getAllPatchesByUsername,
|
|
4
|
+
getAllPatchesSince,
|
|
5
|
+
instanceRemapsStoreName
|
|
6
|
+
} from "./chunk-ZEZGI2TP.js";
|
|
7
|
+
|
|
8
|
+
// ../db_schemas/dist/index.js
|
|
9
|
+
var PatchOperation = /* @__PURE__ */ ((PatchOperation2) => {
|
|
10
|
+
PatchOperation2[PatchOperation2["EditPropertyString"] = 1] = "EditPropertyString";
|
|
11
|
+
PatchOperation2[PatchOperation2["EditPropertyNumber"] = 2] = "EditPropertyNumber";
|
|
12
|
+
PatchOperation2[PatchOperation2["EditInstanceFieldString"] = 3] = "EditInstanceFieldString";
|
|
13
|
+
PatchOperation2[PatchOperation2["EditInstanceFieldNumber"] = 4] = "EditInstanceFieldNumber";
|
|
14
|
+
PatchOperation2[PatchOperation2["EditRelation"] = 5] = "EditRelation";
|
|
15
|
+
PatchOperation2[PatchOperation2["SetAlias"] = 6] = "SetAlias";
|
|
16
|
+
PatchOperation2[PatchOperation2["CreateRecord"] = 7] = "CreateRecord";
|
|
17
|
+
PatchOperation2[PatchOperation2["AddInstance"] = 8] = "AddInstance";
|
|
18
|
+
return PatchOperation2;
|
|
19
|
+
})(PatchOperation || {});
|
|
20
|
+
var PatchAction = /* @__PURE__ */ ((PatchAction2) => {
|
|
21
|
+
PatchAction2[PatchAction2["Remove"] = 0] = "Remove";
|
|
22
|
+
PatchAction2[PatchAction2["Add"] = 1] = "Add";
|
|
23
|
+
return PatchAction2;
|
|
24
|
+
})(PatchAction || {});
|
|
25
|
+
var LANG_ID_ENCODE = {
|
|
26
|
+
eng: 1,
|
|
27
|
+
fra: 2,
|
|
28
|
+
spa: 3,
|
|
29
|
+
por: 4,
|
|
30
|
+
deu: 5,
|
|
31
|
+
zho: 6,
|
|
32
|
+
ara: 7,
|
|
33
|
+
rus: 8,
|
|
34
|
+
jpn: 9,
|
|
35
|
+
kor: 10,
|
|
36
|
+
hin: 11,
|
|
37
|
+
ita: 12,
|
|
38
|
+
nld: 13,
|
|
39
|
+
pol: 14,
|
|
40
|
+
swe: 15,
|
|
41
|
+
tur: 16,
|
|
42
|
+
vie: 17,
|
|
43
|
+
ind: 18,
|
|
44
|
+
tha: 19,
|
|
45
|
+
fas: 20,
|
|
46
|
+
heb: 21,
|
|
47
|
+
ukr: 22,
|
|
48
|
+
// Ethiopian traditions (the "Bible Problem" founding example):
|
|
49
|
+
amh: 23,
|
|
50
|
+
gez: 24,
|
|
51
|
+
tir: 25,
|
|
52
|
+
orm: 26,
|
|
53
|
+
cat: 27
|
|
54
|
+
};
|
|
55
|
+
var LANG_ID_DECODE = Object.fromEntries(
|
|
56
|
+
Object.entries(LANG_ID_ENCODE).map(([k, v]) => [v, k])
|
|
57
|
+
);
|
|
58
|
+
function resolveLayout(version, versionsFile2) {
|
|
59
|
+
const merged = { hash: "", enums: {}, props: {}, instanceFields: {} };
|
|
60
|
+
for (let v = 1; v <= version; v++) {
|
|
61
|
+
const entry = versionsFile2.versions[v];
|
|
62
|
+
if (!entry) continue;
|
|
63
|
+
Object.assign(merged.enums, entry.enums);
|
|
64
|
+
Object.assign(merged.props, entry.props);
|
|
65
|
+
for (const [ot, fields] of Object.entries(entry.instanceFields)) {
|
|
66
|
+
merged.instanceFields[Number(ot)] = [...fields];
|
|
67
|
+
}
|
|
68
|
+
merged.hash = entry.hash;
|
|
69
|
+
}
|
|
70
|
+
return merged;
|
|
71
|
+
}
|
|
72
|
+
function getPropBits(layout, propertyId) {
|
|
73
|
+
return layout.props[propertyId]?.bits ?? 32;
|
|
74
|
+
}
|
|
75
|
+
function isSignedProp(layout, propertyId) {
|
|
76
|
+
const t = layout.props[propertyId]?.type;
|
|
77
|
+
return t === void 0 || t === "number";
|
|
78
|
+
}
|
|
79
|
+
function checked(value, bits, field) {
|
|
80
|
+
if (!Number.isInteger(value)) {
|
|
81
|
+
throw new Error(`[db_schema_v2] ${field} = ${value} is not an integer`);
|
|
82
|
+
}
|
|
83
|
+
if (bits === 32) {
|
|
84
|
+
if (value < 0 || value >= 2 ** 32) {
|
|
85
|
+
throw new Error(`[db_schema_v2] ${field} = ${value} exceeds its ${bits}-bit range`);
|
|
86
|
+
}
|
|
87
|
+
return BigInt(value >>> 0);
|
|
88
|
+
} else {
|
|
89
|
+
if (value < 0 || value >= 2 ** bits) {
|
|
90
|
+
throw new Error(`[db_schema_v2] ${field} = ${value} exceeds its ${bits}-bit range (0..${2 ** bits - 1})`);
|
|
91
|
+
}
|
|
92
|
+
return BigInt(value);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function checkedValue(value, bits, signed) {
|
|
96
|
+
const ok = Number.isInteger(value) && (signed ? value >= -(2 ** (bits - 1)) && value < 2 ** (bits - 1) : value >= 0 && value < 2 ** bits);
|
|
97
|
+
if (!ok) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
`[db_schema_v2] value = ${value} does not fit in ${bits} ${signed ? "signed" : "unsigned"} bits`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
return BigInt(value) & (1n << BigInt(bits)) - 1n;
|
|
103
|
+
}
|
|
104
|
+
function packPatch(patch, layout) {
|
|
105
|
+
const op = BigInt(patch.operation);
|
|
106
|
+
if (patch.operation === 6) {
|
|
107
|
+
const p = patch;
|
|
108
|
+
return op | checked(p.objectType, 7, "objectType") << 4n | checked(p.fromUid, 32, "fromUid") << 11n | checked(p.toUid, 32, "toUid") << 43n;
|
|
109
|
+
}
|
|
110
|
+
if (patch.operation === 7) {
|
|
111
|
+
const p = patch;
|
|
112
|
+
if (p.objectId >>> 0 < 2147483648) {
|
|
113
|
+
throw new Error(`[db_schema_v2] CreateRecord objectId must have high bit set: ${p.objectId}`);
|
|
114
|
+
}
|
|
115
|
+
return op | checked(p.objectType, 7, "objectType") << 4n | checked(p.objectId, 32, "objectId") << 11n | 0n << 43n;
|
|
116
|
+
}
|
|
117
|
+
const bp = patch;
|
|
118
|
+
const base = op | checked(bp.objectType, 7, "objectType") << 4n | checked(bp.objectId, 32, "objectId") << 11n | checked(bp.langId, 8, "langId") << 43n;
|
|
119
|
+
switch (patch.operation) {
|
|
120
|
+
case 2: {
|
|
121
|
+
const p = patch;
|
|
122
|
+
const bits = getPropBits(layout, p.propertyId);
|
|
123
|
+
return base | checked(p.propertyId, 8, "propertyId") << 51n | checkedValue(p.value, bits, isSignedProp(layout, p.propertyId)) << 59n;
|
|
124
|
+
}
|
|
125
|
+
case 1: {
|
|
126
|
+
const p = patch;
|
|
127
|
+
return base | checked(p.propertyId, 8, "propertyId") << 51n;
|
|
128
|
+
}
|
|
129
|
+
case 4: {
|
|
130
|
+
const p = patch;
|
|
131
|
+
const bits = getPropBits(layout, p.propertyId);
|
|
132
|
+
return base | checked(p.instanceIndex, 8, "instanceIndex") << 51n | checked(p.propertyId, 8, "propertyId") << 59n | checkedValue(p.value, bits, isSignedProp(layout, p.propertyId)) << 67n;
|
|
133
|
+
}
|
|
134
|
+
case 3: {
|
|
135
|
+
const p = patch;
|
|
136
|
+
return base | checked(p.instanceIndex, 8, "instanceIndex") << 51n | checked(p.propertyId, 8, "propertyId") << 59n;
|
|
137
|
+
}
|
|
138
|
+
case 5: {
|
|
139
|
+
const p = patch;
|
|
140
|
+
return base | checked(p.relationId, 8, "relationId") << 51n | checked(p.action, 1, "action") << 59n | checked(p.targetId, 32, "targetId") << 60n;
|
|
141
|
+
}
|
|
142
|
+
case 8: {
|
|
143
|
+
const p = patch;
|
|
144
|
+
return base | checked(p.instanceIndex, 8, "instanceIndex") << 51n;
|
|
145
|
+
}
|
|
146
|
+
default:
|
|
147
|
+
throw new Error(`Unknown patch operation: ${patch.operation}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function unpackPatch(packed, layout) {
|
|
151
|
+
const opNum = Number(packed & 15n);
|
|
152
|
+
if (opNum === 6) {
|
|
153
|
+
return {
|
|
154
|
+
operation: 6,
|
|
155
|
+
objectType: Number(packed >> 4n & 127n),
|
|
156
|
+
fromUid: Number(packed >> 11n & 0xFFFFFFFFn),
|
|
157
|
+
toUid: Number(packed >> 43n & 0xFFFFFFFFn)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (opNum === 7) {
|
|
161
|
+
const objectId2 = Number(packed >> 11n & 0xFFFFFFFFn);
|
|
162
|
+
if (objectId2 >>> 0 < 2147483648) {
|
|
163
|
+
throw new Error(`[db_schema_v2] CreateRecord objectId must have high bit set: ${objectId2}`);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
operation: 7,
|
|
167
|
+
objectType: Number(packed >> 4n & 127n),
|
|
168
|
+
objectId: objectId2,
|
|
169
|
+
langId: 0
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const objectType = Number(packed >> 4n & 127n);
|
|
173
|
+
const objectId = Number(packed >> 11n & 0xFFFFFFFFn);
|
|
174
|
+
const langId = Number(packed >> 43n & 255n);
|
|
175
|
+
const base = { operation: opNum, objectType, objectId, langId };
|
|
176
|
+
switch (opNum) {
|
|
177
|
+
case 2: {
|
|
178
|
+
const propertyId = Number(packed >> 51n & 255n);
|
|
179
|
+
const bits = getPropBits(layout, propertyId);
|
|
180
|
+
const mask = (1n << BigInt(bits)) - 1n;
|
|
181
|
+
const raw = packed >> 59n & mask;
|
|
182
|
+
const value = isSignedProp(layout, propertyId) ? Number(BigInt.asIntN(bits, raw)) : Number(raw);
|
|
183
|
+
return { ...base, propertyId, value };
|
|
184
|
+
}
|
|
185
|
+
case 1: {
|
|
186
|
+
const propertyId = Number(packed >> 51n & 255n);
|
|
187
|
+
return { ...base, propertyId, value: "" };
|
|
188
|
+
}
|
|
189
|
+
case 4: {
|
|
190
|
+
const instanceIndex = Number(packed >> 51n & 255n);
|
|
191
|
+
const propertyId = Number(packed >> 59n & 255n);
|
|
192
|
+
const bits = getPropBits(layout, propertyId);
|
|
193
|
+
const mask = (1n << BigInt(bits)) - 1n;
|
|
194
|
+
const raw = packed >> 67n & mask;
|
|
195
|
+
const value = isSignedProp(layout, propertyId) ? Number(BigInt.asIntN(bits, raw)) : Number(raw);
|
|
196
|
+
return { ...base, instanceIndex, propertyId, value };
|
|
197
|
+
}
|
|
198
|
+
case 3: {
|
|
199
|
+
const instanceIndex = Number(packed >> 51n & 255n);
|
|
200
|
+
const propertyId = Number(packed >> 59n & 255n);
|
|
201
|
+
return { ...base, instanceIndex, propertyId, value: "" };
|
|
202
|
+
}
|
|
203
|
+
case 5: {
|
|
204
|
+
const relationId = Number(packed >> 51n & 255n);
|
|
205
|
+
const action = Number(packed >> 59n & 1n);
|
|
206
|
+
const targetId = Number(packed >> 60n & 0xFFFFFFFFn);
|
|
207
|
+
return { ...base, relationId, action, targetId };
|
|
208
|
+
}
|
|
209
|
+
case 8: {
|
|
210
|
+
const instanceIndex = Number(packed >> 51n & 255n);
|
|
211
|
+
return { ...base, instanceIndex };
|
|
212
|
+
}
|
|
213
|
+
default:
|
|
214
|
+
throw new Error(`Unknown packed operation: ${opNum}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function patchToEvm(patches, layout, version) {
|
|
218
|
+
const result = [];
|
|
219
|
+
const textIndex = [];
|
|
220
|
+
const textData = [];
|
|
221
|
+
for (let i = 0; i < patches.length; i++) {
|
|
222
|
+
const patch = patches[i];
|
|
223
|
+
result.push(packPatch(patch, layout));
|
|
224
|
+
if (patch.operation === 1) {
|
|
225
|
+
textIndex.push(i);
|
|
226
|
+
textData.push(patch.value);
|
|
227
|
+
} else if (patch.operation === 3) {
|
|
228
|
+
textIndex.push(i);
|
|
229
|
+
textData.push(patch.value);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return { version, patches: result, textIndex, textData };
|
|
233
|
+
}
|
|
234
|
+
function evmToPatch(payload, versionsFile2) {
|
|
235
|
+
const layout = resolveLayout(payload.version, versionsFile2);
|
|
236
|
+
const textMap = /* @__PURE__ */ new Map();
|
|
237
|
+
for (let i = 0; i < payload.textIndex.length; i++) {
|
|
238
|
+
textMap.set(payload.textIndex[i], payload.textData[i]);
|
|
239
|
+
}
|
|
240
|
+
return payload.patches.map((packed, i) => {
|
|
241
|
+
const patch = unpackPatch(packed, layout);
|
|
242
|
+
if (patch.operation === 1) {
|
|
243
|
+
patch.value = textMap.get(i) ?? "";
|
|
244
|
+
} else if (patch.operation === 3) {
|
|
245
|
+
patch.value = textMap.get(i) ?? "";
|
|
246
|
+
}
|
|
247
|
+
return patch;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/models/interfaces.ts
|
|
252
|
+
var LANG_AGNOSTIC = "";
|
|
253
|
+
var isEvmPatch = (item) => item.operation !== void 0;
|
|
254
|
+
|
|
255
|
+
// src/models/dates.ts
|
|
256
|
+
function monthDiff(d1, d2) {
|
|
257
|
+
var months;
|
|
258
|
+
months = (d2.getFullYear() - d1.getFullYear()) * 12;
|
|
259
|
+
months -= d1.getMonth();
|
|
260
|
+
months += d2.getMonth();
|
|
261
|
+
return months <= 0 ? 0 : months;
|
|
262
|
+
}
|
|
263
|
+
var zeroDate = new Date(2025, 4, 1);
|
|
264
|
+
var inceptionDate = Math.floor(new Date(2025, 11, 1, 0, 0, 0).getTime() / 1e3);
|
|
265
|
+
var DateUtils = {
|
|
266
|
+
now: () => Math.floor(Date.now() / 1e3) - inceptionDate,
|
|
267
|
+
serialize: (d) => {
|
|
268
|
+
const dv = new DataView(new ArrayBuffer(4));
|
|
269
|
+
dv.setUint32(0, d);
|
|
270
|
+
return dv.buffer;
|
|
271
|
+
},
|
|
272
|
+
toNumber: (d) => Math.floor(d.getTime() / 1e3),
|
|
273
|
+
fromNumber: (i) => new Date(i * 1e3),
|
|
274
|
+
findNowBucket: () => {
|
|
275
|
+
const now = /* @__PURE__ */ new Date();
|
|
276
|
+
if (now.getTime() < zeroDate.getTime()) {
|
|
277
|
+
throw new Error(`now ${now} is before zeroDate ${zeroDate}`);
|
|
278
|
+
}
|
|
279
|
+
return monthDiff(zeroDate, now);
|
|
280
|
+
},
|
|
281
|
+
findDateBucket: (d) => {
|
|
282
|
+
if (d.getTime() < zeroDate.getTime()) {
|
|
283
|
+
throw new Error(`now ${d} is before zeroDate ${zeroDate}`);
|
|
284
|
+
}
|
|
285
|
+
return monthDiff(zeroDate, d);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/models/enums.ts
|
|
290
|
+
var ActionTypes = /* @__PURE__ */ ((ActionTypes2) => {
|
|
291
|
+
ActionTypes2[ActionTypes2["Visit"] = 0] = "Visit";
|
|
292
|
+
ActionTypes2[ActionTypes2["VisitPart"] = 1] = "VisitPart";
|
|
293
|
+
ActionTypes2[ActionTypes2["Download"] = 2] = "Download";
|
|
294
|
+
ActionTypes2[ActionTypes2["Rate"] = 3] = "Rate";
|
|
295
|
+
ActionTypes2[ActionTypes2["RatePart"] = 4] = "RatePart";
|
|
296
|
+
ActionTypes2[ActionTypes2["Share"] = 5] = "Share";
|
|
297
|
+
ActionTypes2[ActionTypes2["SharePart"] = 6] = "SharePart";
|
|
298
|
+
return ActionTypes2;
|
|
299
|
+
})(ActionTypes || {});
|
|
300
|
+
var WorkerCommands = /* @__PURE__ */ ((WorkerCommands2) => {
|
|
301
|
+
WorkerCommands2["Init"] = "init";
|
|
302
|
+
WorkerCommands2["SavePatches"] = "savePatches";
|
|
303
|
+
WorkerCommands2["GetRecord"] = "getRecord";
|
|
304
|
+
WorkerCommands2["LoadLanguage"] = "loadLanguage";
|
|
305
|
+
return WorkerCommands2;
|
|
306
|
+
})(WorkerCommands || {});
|
|
307
|
+
var Rating = /* @__PURE__ */ ((Rating2) => {
|
|
308
|
+
Rating2[Rating2["None"] = 0] = "None";
|
|
309
|
+
Rating2[Rating2["New"] = 1] = "New";
|
|
310
|
+
Rating2[Rating2["Keep"] = 2] = "Keep";
|
|
311
|
+
Rating2[Rating2["Trash"] = 3] = "Trash";
|
|
312
|
+
Rating2[Rating2["Shared"] = 4] = "Shared";
|
|
313
|
+
return Rating2;
|
|
314
|
+
})(Rating || {});
|
|
315
|
+
var WorkerEvent = /* @__PURE__ */ ((WorkerEvent2) => {
|
|
316
|
+
WorkerEvent2["WorkerReady"] = "workerready";
|
|
317
|
+
WorkerEvent2["WorkerLoadingError"] = "workerLoadingError";
|
|
318
|
+
WorkerEvent2["DownloadStarted"] = "downloadStarted";
|
|
319
|
+
WorkerEvent2["DownloadFinished"] = "downloadFinished";
|
|
320
|
+
WorkerEvent2["DownloadError"] = "downloadError";
|
|
321
|
+
WorkerEvent2["LevelUpdated"] = "levelUpdated";
|
|
322
|
+
return WorkerEvent2;
|
|
323
|
+
})(WorkerEvent || {});
|
|
324
|
+
var DownloadState = /* @__PURE__ */ ((DownloadState2) => {
|
|
325
|
+
DownloadState2[DownloadState2["Unknown"] = 0] = "Unknown";
|
|
326
|
+
DownloadState2[DownloadState2["Pending"] = 1] = "Pending";
|
|
327
|
+
DownloadState2[DownloadState2["InProgress"] = 2] = "InProgress";
|
|
328
|
+
DownloadState2[DownloadState2["Done"] = 3] = "Done";
|
|
329
|
+
DownloadState2[DownloadState2["Error"] = 4] = "Error";
|
|
330
|
+
return DownloadState2;
|
|
331
|
+
})(DownloadState || {});
|
|
332
|
+
var SidecarType = /* @__PURE__ */ ((SidecarType2) => {
|
|
333
|
+
SidecarType2[SidecarType2["Slim"] = 0] = "Slim";
|
|
334
|
+
SidecarType2[SidecarType2["Extended"] = 1] = "Extended";
|
|
335
|
+
SidecarType2[SidecarType2["Provenance"] = 2] = "Provenance";
|
|
336
|
+
return SidecarType2;
|
|
337
|
+
})(SidecarType || {});
|
|
338
|
+
|
|
339
|
+
// src/models/sanitizer.ts
|
|
340
|
+
function sanitizeText(text) {
|
|
341
|
+
if (typeof text !== "string") return text;
|
|
342
|
+
let sanitized = text.replace(/<\/?[^>]+(>|$)/g, "");
|
|
343
|
+
const dangerousProtocols = /javascript:|data:|vbscript:|onclick|onerror|onload|onmouseover/gi;
|
|
344
|
+
sanitized = sanitized.replace(dangerousProtocols, "[REDACTED]");
|
|
345
|
+
return sanitized;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// ../db_schemas/dist/versions.js
|
|
349
|
+
var versions_default = {
|
|
350
|
+
"current": 2,
|
|
351
|
+
"versions": {
|
|
352
|
+
"1": {
|
|
353
|
+
"hash": "de10ae90e292fd0d",
|
|
354
|
+
"enums": {
|
|
355
|
+
"BookMethod": {
|
|
356
|
+
"bits": 3,
|
|
357
|
+
"values": [
|
|
358
|
+
"Unknown",
|
|
359
|
+
"Scan",
|
|
360
|
+
"NativeDigital",
|
|
361
|
+
"OCR",
|
|
362
|
+
"AiTranslation"
|
|
363
|
+
]
|
|
364
|
+
},
|
|
365
|
+
"CopyrightStatus": {
|
|
366
|
+
"bits": 2,
|
|
367
|
+
"values": [
|
|
368
|
+
"Unknown",
|
|
369
|
+
"PublicDomain",
|
|
370
|
+
"CreativeCommons",
|
|
371
|
+
"AllRightsReserved"
|
|
372
|
+
]
|
|
373
|
+
},
|
|
374
|
+
"QualityScore": {
|
|
375
|
+
"bits": 3,
|
|
376
|
+
"values": [
|
|
377
|
+
"None",
|
|
378
|
+
"Poor",
|
|
379
|
+
"Fair",
|
|
380
|
+
"Good",
|
|
381
|
+
"VeryGood",
|
|
382
|
+
"Excellent"
|
|
383
|
+
]
|
|
384
|
+
},
|
|
385
|
+
"RecordingStatus": {
|
|
386
|
+
"bits": 2,
|
|
387
|
+
"values": [
|
|
388
|
+
"Pending",
|
|
389
|
+
"Active",
|
|
390
|
+
"Completed",
|
|
391
|
+
"Archived"
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
},
|
|
395
|
+
"props": {
|
|
396
|
+
"0": {
|
|
397
|
+
"name": "title",
|
|
398
|
+
"type": "string",
|
|
399
|
+
"bits": 0
|
|
400
|
+
},
|
|
401
|
+
"1": {
|
|
402
|
+
"name": "description",
|
|
403
|
+
"type": "string",
|
|
404
|
+
"bits": 0
|
|
405
|
+
},
|
|
406
|
+
"2": {
|
|
407
|
+
"name": "originalLang",
|
|
408
|
+
"type": "string",
|
|
409
|
+
"bits": 0
|
|
410
|
+
},
|
|
411
|
+
"3": {
|
|
412
|
+
"name": "ageGradeBand",
|
|
413
|
+
"type": "number",
|
|
414
|
+
"bits": 8
|
|
415
|
+
},
|
|
416
|
+
"4": {
|
|
417
|
+
"name": "previewTxId",
|
|
418
|
+
"type": "string",
|
|
419
|
+
"bits": 0
|
|
420
|
+
},
|
|
421
|
+
"5": {
|
|
422
|
+
"name": "safe",
|
|
423
|
+
"type": "boolean",
|
|
424
|
+
"bits": 1
|
|
425
|
+
},
|
|
426
|
+
"6": {
|
|
427
|
+
"name": "deleted",
|
|
428
|
+
"type": "boolean",
|
|
429
|
+
"bits": 1
|
|
430
|
+
},
|
|
431
|
+
"7": {
|
|
432
|
+
"name": "lifecycleStatus",
|
|
433
|
+
"type": "number",
|
|
434
|
+
"bits": 2
|
|
435
|
+
},
|
|
436
|
+
"8": {
|
|
437
|
+
"name": "prerequisites",
|
|
438
|
+
"type": "string",
|
|
439
|
+
"bits": 0
|
|
440
|
+
},
|
|
441
|
+
"9": {
|
|
442
|
+
"name": "deweyDecimal",
|
|
443
|
+
"type": "string",
|
|
444
|
+
"bits": 0
|
|
445
|
+
},
|
|
446
|
+
"10": {
|
|
447
|
+
"name": "locCallNumber",
|
|
448
|
+
"type": "string",
|
|
449
|
+
"bits": 0
|
|
450
|
+
},
|
|
451
|
+
"11": {
|
|
452
|
+
"name": "copyrightStatus",
|
|
453
|
+
"type": "enum",
|
|
454
|
+
"bits": 2,
|
|
455
|
+
"enum": "CopyrightStatus"
|
|
456
|
+
},
|
|
457
|
+
"12": {
|
|
458
|
+
"name": "textQuality",
|
|
459
|
+
"type": "enum",
|
|
460
|
+
"bits": 3,
|
|
461
|
+
"enum": "QualityScore"
|
|
462
|
+
},
|
|
463
|
+
"13": {
|
|
464
|
+
"name": "illustrations",
|
|
465
|
+
"type": "enum",
|
|
466
|
+
"bits": 3,
|
|
467
|
+
"enum": "QualityScore"
|
|
468
|
+
},
|
|
469
|
+
"14": {
|
|
470
|
+
"name": "educationQuality",
|
|
471
|
+
"type": "enum",
|
|
472
|
+
"bits": 3,
|
|
473
|
+
"enum": "QualityScore"
|
|
474
|
+
},
|
|
475
|
+
"15": {
|
|
476
|
+
"name": "practicality",
|
|
477
|
+
"type": "enum",
|
|
478
|
+
"bits": 3,
|
|
479
|
+
"enum": "QualityScore"
|
|
480
|
+
},
|
|
481
|
+
"16": {
|
|
482
|
+
"name": "accessibilityLevel",
|
|
483
|
+
"type": "enum",
|
|
484
|
+
"bits": 3,
|
|
485
|
+
"enum": "QualityScore"
|
|
486
|
+
},
|
|
487
|
+
"17": {
|
|
488
|
+
"name": "teacherMaterials",
|
|
489
|
+
"type": "boolean",
|
|
490
|
+
"bits": 1
|
|
491
|
+
},
|
|
492
|
+
"18": {
|
|
493
|
+
"name": "pedagogicalScaffolding",
|
|
494
|
+
"type": "enum",
|
|
495
|
+
"bits": 3,
|
|
496
|
+
"enum": "QualityScore"
|
|
497
|
+
},
|
|
498
|
+
"19": {
|
|
499
|
+
"name": "clarityOfExplanation",
|
|
500
|
+
"type": "enum",
|
|
501
|
+
"bits": 3,
|
|
502
|
+
"enum": "QualityScore"
|
|
503
|
+
},
|
|
504
|
+
"20": {
|
|
505
|
+
"name": "workedExamples",
|
|
506
|
+
"type": "enum",
|
|
507
|
+
"bits": 3,
|
|
508
|
+
"enum": "QualityScore"
|
|
509
|
+
},
|
|
510
|
+
"21": {
|
|
511
|
+
"name": "exercisesAndAssessment",
|
|
512
|
+
"type": "enum",
|
|
513
|
+
"bits": 3,
|
|
514
|
+
"enum": "QualityScore"
|
|
515
|
+
},
|
|
516
|
+
"22": {
|
|
517
|
+
"name": "selfStudyReadiness",
|
|
518
|
+
"type": "enum",
|
|
519
|
+
"bits": 3,
|
|
520
|
+
"enum": "QualityScore"
|
|
521
|
+
},
|
|
522
|
+
"23": {
|
|
523
|
+
"name": "referenceApparatus",
|
|
524
|
+
"type": "enum",
|
|
525
|
+
"bits": 3,
|
|
526
|
+
"enum": "QualityScore"
|
|
527
|
+
},
|
|
528
|
+
"24": {
|
|
529
|
+
"name": "safetyGuidance",
|
|
530
|
+
"type": "enum",
|
|
531
|
+
"bits": 3,
|
|
532
|
+
"enum": "QualityScore"
|
|
533
|
+
},
|
|
534
|
+
"25": {
|
|
535
|
+
"name": "contentCurrency",
|
|
536
|
+
"type": "enum",
|
|
537
|
+
"bits": 3,
|
|
538
|
+
"enum": "QualityScore"
|
|
539
|
+
},
|
|
540
|
+
"26": {
|
|
541
|
+
"name": "ecoRegeneration",
|
|
542
|
+
"type": "enum",
|
|
543
|
+
"bits": 3,
|
|
544
|
+
"enum": "QualityScore"
|
|
545
|
+
},
|
|
546
|
+
"27": {
|
|
547
|
+
"name": "communityLiving",
|
|
548
|
+
"type": "enum",
|
|
549
|
+
"bits": 3,
|
|
550
|
+
"enum": "QualityScore"
|
|
551
|
+
},
|
|
552
|
+
"28": {
|
|
553
|
+
"name": "promotesPeace",
|
|
554
|
+
"type": "enum",
|
|
555
|
+
"bits": 3,
|
|
556
|
+
"enum": "QualityScore"
|
|
557
|
+
},
|
|
558
|
+
"29": {
|
|
559
|
+
"name": "businessDevelopment",
|
|
560
|
+
"type": "enum",
|
|
561
|
+
"bits": 3,
|
|
562
|
+
"enum": "QualityScore"
|
|
563
|
+
},
|
|
564
|
+
"30": {
|
|
565
|
+
"name": "language",
|
|
566
|
+
"type": "string",
|
|
567
|
+
"bits": 0
|
|
568
|
+
},
|
|
569
|
+
"31": {
|
|
570
|
+
"name": "downloadTxId",
|
|
571
|
+
"type": "string",
|
|
572
|
+
"bits": 0
|
|
573
|
+
},
|
|
574
|
+
"32": {
|
|
575
|
+
"name": "method",
|
|
576
|
+
"type": "enum",
|
|
577
|
+
"bits": 3,
|
|
578
|
+
"enum": "BookMethod"
|
|
579
|
+
},
|
|
580
|
+
"33": {
|
|
581
|
+
"name": "isAiTranslation",
|
|
582
|
+
"type": "boolean",
|
|
583
|
+
"bits": 1
|
|
584
|
+
},
|
|
585
|
+
"34": {
|
|
586
|
+
"name": "aiEngine",
|
|
587
|
+
"type": "string",
|
|
588
|
+
"bits": 0
|
|
589
|
+
},
|
|
590
|
+
"35": {
|
|
591
|
+
"name": "addedAt",
|
|
592
|
+
"type": "number",
|
|
593
|
+
"bits": 32
|
|
594
|
+
},
|
|
595
|
+
"36": {
|
|
596
|
+
"name": "nbPages",
|
|
597
|
+
"type": "number",
|
|
598
|
+
"bits": 16
|
|
599
|
+
},
|
|
600
|
+
"37": {
|
|
601
|
+
"name": "sizeBytes",
|
|
602
|
+
"type": "number",
|
|
603
|
+
"bits": 32
|
|
604
|
+
},
|
|
605
|
+
"38": {
|
|
606
|
+
"name": "publisher",
|
|
607
|
+
"type": "string",
|
|
608
|
+
"bits": 0
|
|
609
|
+
},
|
|
610
|
+
"39": {
|
|
611
|
+
"name": "publicationDate",
|
|
612
|
+
"type": "string",
|
|
613
|
+
"bits": 0
|
|
614
|
+
},
|
|
615
|
+
"40": {
|
|
616
|
+
"name": "publishedAt",
|
|
617
|
+
"type": "string",
|
|
618
|
+
"bits": 0
|
|
619
|
+
},
|
|
620
|
+
"41": {
|
|
621
|
+
"name": "qualityScore",
|
|
622
|
+
"type": "enum",
|
|
623
|
+
"bits": 3,
|
|
624
|
+
"enum": "QualityScore"
|
|
625
|
+
},
|
|
626
|
+
"42": {
|
|
627
|
+
"name": "isbn",
|
|
628
|
+
"type": "string",
|
|
629
|
+
"bits": 0
|
|
630
|
+
},
|
|
631
|
+
"43": {
|
|
632
|
+
"name": "birthDate",
|
|
633
|
+
"type": "string",
|
|
634
|
+
"bits": 0
|
|
635
|
+
},
|
|
636
|
+
"44": {
|
|
637
|
+
"name": "deathDate",
|
|
638
|
+
"type": "string",
|
|
639
|
+
"bits": 0
|
|
640
|
+
},
|
|
641
|
+
"45": {
|
|
642
|
+
"name": "nationality",
|
|
643
|
+
"type": "string",
|
|
644
|
+
"bits": 0
|
|
645
|
+
},
|
|
646
|
+
"46": {
|
|
647
|
+
"name": "wikiUrl",
|
|
648
|
+
"type": "string",
|
|
649
|
+
"bits": 0
|
|
650
|
+
},
|
|
651
|
+
"47": {
|
|
652
|
+
"name": "isniId",
|
|
653
|
+
"type": "string",
|
|
654
|
+
"bits": 0
|
|
655
|
+
},
|
|
656
|
+
"48": {
|
|
657
|
+
"name": "orcidId",
|
|
658
|
+
"type": "string",
|
|
659
|
+
"bits": 0
|
|
660
|
+
},
|
|
661
|
+
"49": {
|
|
662
|
+
"name": "ddcNotation",
|
|
663
|
+
"type": "string",
|
|
664
|
+
"bits": 0
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
"instanceFields": {
|
|
668
|
+
"0": [
|
|
669
|
+
30,
|
|
670
|
+
31,
|
|
671
|
+
32,
|
|
672
|
+
33,
|
|
673
|
+
34,
|
|
674
|
+
35,
|
|
675
|
+
36,
|
|
676
|
+
37,
|
|
677
|
+
38,
|
|
678
|
+
39,
|
|
679
|
+
40,
|
|
680
|
+
41,
|
|
681
|
+
42
|
|
682
|
+
]
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
"2": {
|
|
686
|
+
"hash": "1eb9d7d1ce54fb8d",
|
|
687
|
+
"enums": {},
|
|
688
|
+
"props": {
|
|
689
|
+
"50": {
|
|
690
|
+
"name": "lccNotation",
|
|
691
|
+
"type": "string",
|
|
692
|
+
"bits": 0
|
|
693
|
+
},
|
|
694
|
+
"51": {
|
|
695
|
+
"name": "udcNotation",
|
|
696
|
+
"type": "string",
|
|
697
|
+
"bits": 0
|
|
698
|
+
},
|
|
699
|
+
"52": {
|
|
700
|
+
"name": "clcNotation",
|
|
701
|
+
"type": "string",
|
|
702
|
+
"bits": 0
|
|
703
|
+
},
|
|
704
|
+
"53": {
|
|
705
|
+
"name": "bbkNotation",
|
|
706
|
+
"type": "string",
|
|
707
|
+
"bits": 0
|
|
708
|
+
},
|
|
709
|
+
"54": {
|
|
710
|
+
"name": "tlcNotation",
|
|
711
|
+
"type": "string",
|
|
712
|
+
"bits": 0
|
|
713
|
+
},
|
|
714
|
+
"55": {
|
|
715
|
+
"name": "ccNotation",
|
|
716
|
+
"type": "string",
|
|
717
|
+
"bits": 0
|
|
718
|
+
}
|
|
719
|
+
},
|
|
720
|
+
"instanceFields": {}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
// src/models/versions.ts
|
|
726
|
+
var versionsFile = versions_default;
|
|
727
|
+
var CURRENT_VERSION = versionsFile.current;
|
|
728
|
+
var _currentLayout = null;
|
|
729
|
+
var currentLayout = () => {
|
|
730
|
+
if (!_currentLayout) {
|
|
731
|
+
_currentLayout = resolveLayout(CURRENT_VERSION, versionsFile);
|
|
732
|
+
}
|
|
733
|
+
return _currentLayout;
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
// src/models/patcher.ts
|
|
737
|
+
function debouncePromise(func, wait) {
|
|
738
|
+
let timeout = null;
|
|
739
|
+
let resolves = [];
|
|
740
|
+
return (...args) => {
|
|
741
|
+
if (timeout !== null) {
|
|
742
|
+
clearTimeout(timeout);
|
|
743
|
+
}
|
|
744
|
+
const p = new Promise((resolve, reject) => {
|
|
745
|
+
resolves.push({ resolve, reject });
|
|
746
|
+
});
|
|
747
|
+
timeout = setTimeout(async () => {
|
|
748
|
+
timeout = null;
|
|
749
|
+
const currentResolves = [...resolves];
|
|
750
|
+
resolves = [];
|
|
751
|
+
try {
|
|
752
|
+
const result = await func(...args);
|
|
753
|
+
currentResolves.forEach((r) => r.resolve(result));
|
|
754
|
+
} catch (error) {
|
|
755
|
+
currentResolves.forEach((r) => r.reject(error));
|
|
756
|
+
}
|
|
757
|
+
}, wait);
|
|
758
|
+
return p;
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
var _Patches = class _Patches {
|
|
762
|
+
constructor(username) {
|
|
763
|
+
this.username = username;
|
|
764
|
+
this._patches = [];
|
|
765
|
+
}
|
|
766
|
+
get patches() {
|
|
767
|
+
return this._patches;
|
|
768
|
+
}
|
|
769
|
+
initThread(thread, debounceMs = 2e3) {
|
|
770
|
+
console.log("InitPatchInstance with thread", thread);
|
|
771
|
+
this.thread = thread;
|
|
772
|
+
this.sync = debouncePromise(_Patches.prototype.sync.bind(this), debounceMs);
|
|
773
|
+
if (this._patches.length > 0) {
|
|
774
|
+
this.sync().catch(console.error);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
get threadInstance() {
|
|
778
|
+
return this.thread;
|
|
779
|
+
}
|
|
780
|
+
static onSync(callback) {
|
|
781
|
+
this.onSyncListeners.push(callback);
|
|
782
|
+
}
|
|
783
|
+
static setReplay(replay) {
|
|
784
|
+
this._replaying = replay;
|
|
785
|
+
}
|
|
786
|
+
/** Drops all queued (not yet persisted) patches. Test/reset helper. */
|
|
787
|
+
clearQueue() {
|
|
788
|
+
this._patches = [];
|
|
789
|
+
}
|
|
790
|
+
addPatch(op) {
|
|
791
|
+
if (_Patches._replaying) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
if (isEvmPatch(op)) {
|
|
795
|
+
if (op.operation === PatchOperation.EditPropertyString) {
|
|
796
|
+
op.value = sanitizeText(op.value);
|
|
797
|
+
} else if (op.operation === PatchOperation.EditInstanceFieldString) {
|
|
798
|
+
op.value = sanitizeText(op.value);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
this._patches.push(op);
|
|
802
|
+
this.sync().catch(console.error);
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Last-Writer-Wins consolidation. Walks the queue from the newest entry
|
|
806
|
+
* backwards and keeps only the latest edit per logical slot.
|
|
807
|
+
*
|
|
808
|
+
* The sub-key for property edits incorporates the language code
|
|
809
|
+
* (`${propertyId}:${langId ?? 0}`) so a French string edit never erases
|
|
810
|
+
* a previous English edit (SPEC §2.2). Instance field edits additionally
|
|
811
|
+
* key on the instance index.
|
|
812
|
+
*/
|
|
813
|
+
static cleanData(data) {
|
|
814
|
+
const dataIndex = {};
|
|
815
|
+
const isUndefined = (obj) => typeof obj === "undefined";
|
|
816
|
+
const filteredData = [];
|
|
817
|
+
const keep = (key, subKey, item) => {
|
|
818
|
+
if (isUndefined(dataIndex[key])) {
|
|
819
|
+
dataIndex[key] = {};
|
|
820
|
+
}
|
|
821
|
+
if (isUndefined(dataIndex[key][subKey])) {
|
|
822
|
+
dataIndex[key][subKey] = true;
|
|
823
|
+
filteredData.push(item);
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
const keepOldest = (key, subKey, item) => {
|
|
827
|
+
if (isUndefined(dataIndex[key])) {
|
|
828
|
+
dataIndex[key] = {};
|
|
829
|
+
}
|
|
830
|
+
if (isUndefined(dataIndex[key][subKey])) {
|
|
831
|
+
dataIndex[key][subKey] = filteredData.length;
|
|
832
|
+
filteredData.push(item);
|
|
833
|
+
} else {
|
|
834
|
+
filteredData[dataIndex[key][subKey]] = item;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
for (let i = data.length - 1; i >= 0; i--) {
|
|
838
|
+
const item = data[i];
|
|
839
|
+
if (isEvmPatch(item)) {
|
|
840
|
+
const key2 = `evm-${item.objectType}-${item.objectId ?? item.fromUid}-${item.operation}`;
|
|
841
|
+
switch (item.operation) {
|
|
842
|
+
case PatchOperation.EditPropertyString:
|
|
843
|
+
case PatchOperation.EditPropertyNumber: {
|
|
844
|
+
const d = item;
|
|
845
|
+
keep(key2, `${d.propertyId}:${d.langId ?? 0}`, item);
|
|
846
|
+
break;
|
|
847
|
+
}
|
|
848
|
+
case PatchOperation.EditInstanceFieldString:
|
|
849
|
+
case PatchOperation.EditInstanceFieldNumber: {
|
|
850
|
+
const d = item;
|
|
851
|
+
keep(key2, `${d.instanceIndex}:${d.propertyId}:${d.langId ?? 0}`, item);
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
case PatchOperation.EditRelation: {
|
|
855
|
+
const d = item;
|
|
856
|
+
keep(key2, `${d.relationId}:${d.targetId}`, item);
|
|
857
|
+
break;
|
|
858
|
+
}
|
|
859
|
+
case PatchOperation.SetAlias: {
|
|
860
|
+
const d = item;
|
|
861
|
+
keep(key2, `${d.fromUid}`, item);
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
864
|
+
case PatchOperation.CreateRecord: {
|
|
865
|
+
keep(key2, "create", item);
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
case PatchOperation.AddInstance: {
|
|
869
|
+
const d = item;
|
|
870
|
+
keepOldest(key2, `${d.langId ?? 0}:${d.instanceIndex}`, item);
|
|
871
|
+
break;
|
|
872
|
+
}
|
|
873
|
+
default:
|
|
874
|
+
throw new Error(`unknown patch operation ${item.operation}`);
|
|
875
|
+
}
|
|
876
|
+
continue;
|
|
877
|
+
}
|
|
878
|
+
const op = item;
|
|
879
|
+
const key = `local-${op.objectType}-${op.objectId}-${op.action}`;
|
|
880
|
+
switch (op.action) {
|
|
881
|
+
case 4 /* RatePart */:
|
|
882
|
+
keep(key, `${op.part}`, op);
|
|
883
|
+
break;
|
|
884
|
+
case 6 /* SharePart */:
|
|
885
|
+
keep(key, `${op.part}:${op.socialMediaId}`, op);
|
|
886
|
+
break;
|
|
887
|
+
case 3 /* Rate */:
|
|
888
|
+
keep(key, "seen", op);
|
|
889
|
+
break;
|
|
890
|
+
case 0 /* Visit */:
|
|
891
|
+
case 2 /* Download */:
|
|
892
|
+
case 5 /* Share */:
|
|
893
|
+
case 1 /* VisitPart */:
|
|
894
|
+
filteredData.push(op);
|
|
895
|
+
break;
|
|
896
|
+
default:
|
|
897
|
+
throw new Error(`unknown local action ${op.action}`);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
filteredData.reverse();
|
|
901
|
+
return filteredData;
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Syncs the queued patches to the worker (IndexedDB persistence).
|
|
905
|
+
* Before initThread, patches are retained in the queue (never dropped);
|
|
906
|
+
* initThread flushes them as soon as the worker is available.
|
|
907
|
+
*/
|
|
908
|
+
async sync() {
|
|
909
|
+
if (typeof this.thread === "undefined") {
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
const data = _Patches.cleanData([...this._patches]);
|
|
913
|
+
if (data.length === 0) {
|
|
914
|
+
this._patches = [];
|
|
915
|
+
return true;
|
|
916
|
+
}
|
|
917
|
+
this._patches = [];
|
|
918
|
+
_Patches.onSyncListeners.forEach((cb) => {
|
|
919
|
+
try {
|
|
920
|
+
cb(data);
|
|
921
|
+
} catch (e) {
|
|
922
|
+
console.error(e);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
let savePatchOperation;
|
|
926
|
+
try {
|
|
927
|
+
savePatchOperation = await this.thread.sendRequest({
|
|
928
|
+
cmd: "savePatches" /* SavePatches */,
|
|
929
|
+
payload: {
|
|
930
|
+
username: this.username,
|
|
931
|
+
patches: data
|
|
932
|
+
}
|
|
933
|
+
});
|
|
934
|
+
} catch (err) {
|
|
935
|
+
this._patches.unshift(...data);
|
|
936
|
+
throw err;
|
|
937
|
+
}
|
|
938
|
+
const level = await _Patches.calculateLevel(this.username);
|
|
939
|
+
console.log("level after saving patches", level);
|
|
940
|
+
return savePatchOperation;
|
|
941
|
+
}
|
|
942
|
+
static async calculateLevel(username) {
|
|
943
|
+
const patches = await getAllPatchesByUsername(username);
|
|
944
|
+
const cleaned = this.cleanData(patches);
|
|
945
|
+
let score = 0;
|
|
946
|
+
for (const p of cleaned) {
|
|
947
|
+
if (isEvmPatch(p)) {
|
|
948
|
+
switch (p.operation) {
|
|
949
|
+
case PatchOperation.EditPropertyString:
|
|
950
|
+
case PatchOperation.EditInstanceFieldString:
|
|
951
|
+
score += 4;
|
|
952
|
+
break;
|
|
953
|
+
case PatchOperation.EditPropertyNumber:
|
|
954
|
+
case PatchOperation.EditInstanceFieldNumber:
|
|
955
|
+
score += 2;
|
|
956
|
+
break;
|
|
957
|
+
case PatchOperation.EditRelation:
|
|
958
|
+
score += 3;
|
|
959
|
+
break;
|
|
960
|
+
case PatchOperation.SetAlias:
|
|
961
|
+
score += 5;
|
|
962
|
+
break;
|
|
963
|
+
}
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
switch (p.action) {
|
|
967
|
+
case 1 /* VisitPart */:
|
|
968
|
+
score += 0.5;
|
|
969
|
+
break;
|
|
970
|
+
case 6 /* SharePart */:
|
|
971
|
+
score += 1;
|
|
972
|
+
break;
|
|
973
|
+
case 4 /* RatePart */:
|
|
974
|
+
score += 1;
|
|
975
|
+
break;
|
|
976
|
+
case 3 /* Rate */:
|
|
977
|
+
score += 1;
|
|
978
|
+
break;
|
|
979
|
+
case 0 /* Visit */:
|
|
980
|
+
score += 1;
|
|
981
|
+
break;
|
|
982
|
+
case 5 /* Share */:
|
|
983
|
+
score += 2;
|
|
984
|
+
break;
|
|
985
|
+
case 2 /* Download */:
|
|
986
|
+
score += 3;
|
|
987
|
+
break;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
const level = score / 7;
|
|
991
|
+
if (typeof window !== "undefined" && typeof CustomEvent !== "undefined") {
|
|
992
|
+
const evt = new CustomEvent("LevelUpdate", {
|
|
993
|
+
detail: { level, username },
|
|
994
|
+
bubbles: true
|
|
995
|
+
});
|
|
996
|
+
window.dispatchEvent(evt);
|
|
997
|
+
}
|
|
998
|
+
return level;
|
|
999
|
+
}
|
|
1000
|
+
};
|
|
1001
|
+
_Patches._replaying = false;
|
|
1002
|
+
_Patches.onSyncListeners = [];
|
|
1003
|
+
var Patches = _Patches;
|
|
1004
|
+
var patchesMap = /* @__PURE__ */ new Map();
|
|
1005
|
+
var PatchInstance = new Patches("mine");
|
|
1006
|
+
patchesMap.set("mine", PatchInstance);
|
|
1007
|
+
var deserializePatches = async (username, payload) => {
|
|
1008
|
+
const operations = evmToPatch(payload, versionsFile);
|
|
1009
|
+
console.log(`[Patches] deserializePatches: writing ${operations.length} restored patches for ${username}`);
|
|
1010
|
+
await bulkAddPatches(username, operations);
|
|
1011
|
+
};
|
|
1012
|
+
var serializePatches = async (fromIndex, toIndex) => {
|
|
1013
|
+
const stored = await getAllPatchesSince("mine", fromIndex);
|
|
1014
|
+
const evmPatches = stored.slice(0, toIndex - fromIndex).filter(isEvmPatch).map(({ pk, username, ...op }) => op).map((op) => {
|
|
1015
|
+
if (op.operation === PatchOperation.EditPropertyString) {
|
|
1016
|
+
op.value = sanitizeText(op.value);
|
|
1017
|
+
} else if (op.operation === PatchOperation.EditInstanceFieldString) {
|
|
1018
|
+
op.value = sanitizeText(op.value);
|
|
1019
|
+
}
|
|
1020
|
+
return op;
|
|
1021
|
+
});
|
|
1022
|
+
return patchToEvm(evmPatches, currentLayout(), CURRENT_VERSION);
|
|
1023
|
+
};
|
|
1024
|
+
var getPatchInstanceByAccount = (account) => {
|
|
1025
|
+
if (!patchesMap.has(account)) {
|
|
1026
|
+
console.warn(`Account ${account} does not exist in patchesInstances \u2014 creating a new one`);
|
|
1027
|
+
const p = new Patches(account);
|
|
1028
|
+
p.initThread(PatchInstance.threadInstance);
|
|
1029
|
+
patchesMap.set(account, p);
|
|
1030
|
+
}
|
|
1031
|
+
return patchesMap.get(account);
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// src/models/stats.ts
|
|
1035
|
+
var StatsStore = /* @__PURE__ */ new Map();
|
|
1036
|
+
var check = (objectType, objectId) => {
|
|
1037
|
+
if (!StatsStore.has(objectType)) {
|
|
1038
|
+
StatsStore.set(objectType, /* @__PURE__ */ new Map());
|
|
1039
|
+
}
|
|
1040
|
+
if (!StatsStore.get(objectType).has(objectId)) {
|
|
1041
|
+
StatsStore.get(objectType).set(objectId, {
|
|
1042
|
+
visits: [],
|
|
1043
|
+
downloads: [],
|
|
1044
|
+
rating: 0 /* None */,
|
|
1045
|
+
socialMediaId: [],
|
|
1046
|
+
parts: {}
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
var PopulateStatsStore = (operations) => {
|
|
1051
|
+
for (const op of operations) {
|
|
1052
|
+
check(op.objectType, op.objectId);
|
|
1053
|
+
const map = StatsStore.get(op.objectType);
|
|
1054
|
+
const stats = map.get(op.objectId);
|
|
1055
|
+
switch (op.action) {
|
|
1056
|
+
case 0 /* Visit */:
|
|
1057
|
+
stats.visits.push(DateUtils.now());
|
|
1058
|
+
break;
|
|
1059
|
+
case 2 /* Download */:
|
|
1060
|
+
stats.downloads.push(DateUtils.now());
|
|
1061
|
+
break;
|
|
1062
|
+
case 1 /* VisitPart */:
|
|
1063
|
+
if (stats.parts[op.part]) {
|
|
1064
|
+
stats.parts[op.part].visits.push(DateUtils.now());
|
|
1065
|
+
} else {
|
|
1066
|
+
stats.parts[op.part] = {
|
|
1067
|
+
rating: 0 /* None */,
|
|
1068
|
+
visits: [DateUtils.now()],
|
|
1069
|
+
socialMediaId: []
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
break;
|
|
1073
|
+
case 4 /* RatePart */:
|
|
1074
|
+
if (stats.parts[op.part]) {
|
|
1075
|
+
stats.parts[op.part].rating = op.rate;
|
|
1076
|
+
} else {
|
|
1077
|
+
stats.parts[op.part] = {
|
|
1078
|
+
rating: op.rate,
|
|
1079
|
+
visits: [],
|
|
1080
|
+
socialMediaId: []
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
break;
|
|
1084
|
+
case 3 /* Rate */:
|
|
1085
|
+
stats.rating = op.rate;
|
|
1086
|
+
break;
|
|
1087
|
+
case 6 /* SharePart */:
|
|
1088
|
+
if (stats.parts[op.part]) {
|
|
1089
|
+
stats.parts[op.part].socialMediaId.push(op.socialMediaId);
|
|
1090
|
+
} else {
|
|
1091
|
+
stats.parts[op.part] = {
|
|
1092
|
+
rating: 0 /* None */,
|
|
1093
|
+
visits: [],
|
|
1094
|
+
socialMediaId: [op.socialMediaId]
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
break;
|
|
1098
|
+
case 5 /* Share */:
|
|
1099
|
+
stats.socialMediaId.push(op.socialMediaId);
|
|
1100
|
+
break;
|
|
1101
|
+
default:
|
|
1102
|
+
break;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
var DownloadsByType = (objectType) => {
|
|
1107
|
+
if (!StatsStore.has(objectType)) {
|
|
1108
|
+
return [];
|
|
1109
|
+
}
|
|
1110
|
+
const map = StatsStore.get(objectType);
|
|
1111
|
+
return Array.from(map.entries()).filter(([, value]) => value.downloads.length > 0).map(([k]) => k);
|
|
1112
|
+
};
|
|
1113
|
+
var VisitsByType = (objectType) => {
|
|
1114
|
+
if (!StatsStore.has(objectType)) {
|
|
1115
|
+
return [];
|
|
1116
|
+
}
|
|
1117
|
+
const map = StatsStore.get(objectType);
|
|
1118
|
+
return Array.from(map.entries()).filter(([, value]) => value.visits.length > 0).map(([k]) => k);
|
|
1119
|
+
};
|
|
1120
|
+
var FavoritesByTypes = (objectType) => {
|
|
1121
|
+
if (!StatsStore.has(objectType)) {
|
|
1122
|
+
return [];
|
|
1123
|
+
}
|
|
1124
|
+
const map = StatsStore.get(objectType);
|
|
1125
|
+
const result = Array.from(map.keys()).filter((id) => {
|
|
1126
|
+
const summary = map.get(id);
|
|
1127
|
+
return summary.visits.length > 0 || summary.downloads.length > 0 || [2 /* Keep */, 1 /* New */, 4 /* Shared */].includes(summary.rating);
|
|
1128
|
+
}).map((id) => {
|
|
1129
|
+
const summary = map.get(id);
|
|
1130
|
+
return { id, nbVisits: summary.visits.length, rating: summary.rating };
|
|
1131
|
+
});
|
|
1132
|
+
result.sort((a, b) => b.nbVisits - a.nbVisits);
|
|
1133
|
+
return result;
|
|
1134
|
+
};
|
|
1135
|
+
var Stats = class {
|
|
1136
|
+
constructor(objectId, objectType) {
|
|
1137
|
+
this.objectId = objectId;
|
|
1138
|
+
this.objectType = objectType;
|
|
1139
|
+
}
|
|
1140
|
+
favoriteParts() {
|
|
1141
|
+
if (!StatsStore.has(this.objectType)) {
|
|
1142
|
+
return [];
|
|
1143
|
+
}
|
|
1144
|
+
const map = StatsStore.get(this.objectType);
|
|
1145
|
+
if (!map.has(this.objectId)) {
|
|
1146
|
+
return [];
|
|
1147
|
+
}
|
|
1148
|
+
const summary = map.get(this.objectId);
|
|
1149
|
+
const result = Object.keys(summary.parts).map((partId) => {
|
|
1150
|
+
return {
|
|
1151
|
+
partId: parseInt(partId),
|
|
1152
|
+
nbVisits: summary.parts[partId].visits.length,
|
|
1153
|
+
rating: summary.parts[partId].rating
|
|
1154
|
+
};
|
|
1155
|
+
});
|
|
1156
|
+
result.sort((a, b) => b.nbVisits - a.nbVisits);
|
|
1157
|
+
return result;
|
|
1158
|
+
}
|
|
1159
|
+
check() {
|
|
1160
|
+
check(this.objectType, this.objectId);
|
|
1161
|
+
}
|
|
1162
|
+
visit() {
|
|
1163
|
+
const op = {
|
|
1164
|
+
action: 0 /* Visit */,
|
|
1165
|
+
ts: DateUtils.now(),
|
|
1166
|
+
objectId: this.objectId,
|
|
1167
|
+
objectType: this.objectType
|
|
1168
|
+
};
|
|
1169
|
+
PopulateStatsStore([op]);
|
|
1170
|
+
PatchInstance.addPatch(op);
|
|
1171
|
+
}
|
|
1172
|
+
download() {
|
|
1173
|
+
const op = {
|
|
1174
|
+
objectType: this.objectType,
|
|
1175
|
+
objectId: this.objectId,
|
|
1176
|
+
ts: DateUtils.now(),
|
|
1177
|
+
action: 2 /* Download */
|
|
1178
|
+
};
|
|
1179
|
+
PopulateStatsStore([op]);
|
|
1180
|
+
PatchInstance.addPatch(op);
|
|
1181
|
+
}
|
|
1182
|
+
get rating() {
|
|
1183
|
+
this.check();
|
|
1184
|
+
return StatsStore.get(this.objectType)?.get(this.objectId)?.rating;
|
|
1185
|
+
}
|
|
1186
|
+
set rating(rating) {
|
|
1187
|
+
const op = {
|
|
1188
|
+
objectType: this.objectType,
|
|
1189
|
+
objectId: this.objectId,
|
|
1190
|
+
ts: DateUtils.now(),
|
|
1191
|
+
action: 3 /* Rate */,
|
|
1192
|
+
rate: rating
|
|
1193
|
+
};
|
|
1194
|
+
PopulateStatsStore([op]);
|
|
1195
|
+
PatchInstance.addPatch(op);
|
|
1196
|
+
}
|
|
1197
|
+
share(socialMediaId) {
|
|
1198
|
+
const op = {
|
|
1199
|
+
objectType: this.objectType,
|
|
1200
|
+
objectId: this.objectId,
|
|
1201
|
+
ts: DateUtils.now(),
|
|
1202
|
+
action: 5 /* Share */,
|
|
1203
|
+
socialMediaId
|
|
1204
|
+
};
|
|
1205
|
+
PopulateStatsStore([op]);
|
|
1206
|
+
PatchInstance.addPatch(op);
|
|
1207
|
+
}
|
|
1208
|
+
ratePart(partId, rating) {
|
|
1209
|
+
const op = {
|
|
1210
|
+
objectType: this.objectType,
|
|
1211
|
+
objectId: this.objectId,
|
|
1212
|
+
ts: DateUtils.now(),
|
|
1213
|
+
action: 4 /* RatePart */,
|
|
1214
|
+
part: partId,
|
|
1215
|
+
rate: rating
|
|
1216
|
+
};
|
|
1217
|
+
PopulateStatsStore([op]);
|
|
1218
|
+
PatchInstance.addPatch(op);
|
|
1219
|
+
}
|
|
1220
|
+
visitPart(partId) {
|
|
1221
|
+
const op = {
|
|
1222
|
+
objectType: this.objectType,
|
|
1223
|
+
objectId: this.objectId,
|
|
1224
|
+
ts: DateUtils.now(),
|
|
1225
|
+
action: 1 /* VisitPart */,
|
|
1226
|
+
part: partId
|
|
1227
|
+
};
|
|
1228
|
+
PopulateStatsStore([op]);
|
|
1229
|
+
PatchInstance.addPatch(op);
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1233
|
+
// src/models/versioning.ts
|
|
1234
|
+
var versioning = /* @__PURE__ */ new Map();
|
|
1235
|
+
var currentUsername = "mine";
|
|
1236
|
+
var collectionFor = (objectType, objectId) => {
|
|
1237
|
+
if (!versioning.has(objectType)) {
|
|
1238
|
+
versioning.set(objectType, /* @__PURE__ */ new Map());
|
|
1239
|
+
}
|
|
1240
|
+
const collection = versioning.get(objectType);
|
|
1241
|
+
if (!collection.has(objectId)) {
|
|
1242
|
+
collection.set(objectId, {
|
|
1243
|
+
createdBy: currentUsername,
|
|
1244
|
+
properties: /* @__PURE__ */ new Map(),
|
|
1245
|
+
relations: /* @__PURE__ */ new Map()
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
return collection.get(objectId);
|
|
1249
|
+
};
|
|
1250
|
+
var track = (patch) => {
|
|
1251
|
+
if (Patches._replaying) {
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1254
|
+
switch (patch.operation) {
|
|
1255
|
+
case PatchOperation.EditPropertyString:
|
|
1256
|
+
case PatchOperation.EditPropertyNumber: {
|
|
1257
|
+
const op = patch;
|
|
1258
|
+
const entry = collectionFor(op.objectType, op.objectId);
|
|
1259
|
+
if (!entry.properties.has(op.propertyId)) {
|
|
1260
|
+
entry.properties.set(op.propertyId, []);
|
|
1261
|
+
}
|
|
1262
|
+
entry.properties.get(op.propertyId).push({
|
|
1263
|
+
username: currentUsername,
|
|
1264
|
+
value: op.value,
|
|
1265
|
+
langId: op.langId
|
|
1266
|
+
});
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
case PatchOperation.EditRelation: {
|
|
1270
|
+
const op = patch;
|
|
1271
|
+
const entry = collectionFor(op.objectType, op.objectId);
|
|
1272
|
+
if (!entry.relations.has(op.relationId)) {
|
|
1273
|
+
entry.relations.set(op.relationId, []);
|
|
1274
|
+
}
|
|
1275
|
+
entry.relations.get(op.relationId).push({
|
|
1276
|
+
username: currentUsername,
|
|
1277
|
+
value: [op.action === PatchAction.Add ? "+" : "-", op.targetId]
|
|
1278
|
+
});
|
|
1279
|
+
break;
|
|
1280
|
+
}
|
|
1281
|
+
default:
|
|
1282
|
+
break;
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
|
|
1286
|
+
// src/models/uidFactory.ts
|
|
1287
|
+
function isUserCreated(wireId) {
|
|
1288
|
+
return (wireId >>> 0 & 2147483648) !== 0;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/models/db.ts
|
|
1292
|
+
var systems = /* @__PURE__ */ new Set();
|
|
1293
|
+
function addReactivitySystem(sys) {
|
|
1294
|
+
systems.add(sys);
|
|
1295
|
+
return () => {
|
|
1296
|
+
systems.delete(sys);
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
function setReactivitySystem(sys) {
|
|
1300
|
+
systems.clear();
|
|
1301
|
+
if (sys) systems.add(sys);
|
|
1302
|
+
}
|
|
1303
|
+
var dbReactivity = {
|
|
1304
|
+
track(obj) {
|
|
1305
|
+
for (const s of systems) s.track(obj);
|
|
1306
|
+
},
|
|
1307
|
+
trigger(obj) {
|
|
1308
|
+
for (const s of systems) s.trigger(obj);
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
var LruCache = class {
|
|
1312
|
+
constructor(limit) {
|
|
1313
|
+
this.limit = limit;
|
|
1314
|
+
this.map = /* @__PURE__ */ new Map();
|
|
1315
|
+
this._pinned = /* @__PURE__ */ new Set();
|
|
1316
|
+
this._warnedOverflow = false;
|
|
1317
|
+
}
|
|
1318
|
+
get size() {
|
|
1319
|
+
return this.map.size;
|
|
1320
|
+
}
|
|
1321
|
+
get(key) {
|
|
1322
|
+
if (!this.map.has(key)) return void 0;
|
|
1323
|
+
const val = this.map.get(key);
|
|
1324
|
+
this.map.delete(key);
|
|
1325
|
+
this.map.set(key, val);
|
|
1326
|
+
return val;
|
|
1327
|
+
}
|
|
1328
|
+
set(key, val) {
|
|
1329
|
+
if (this.map.has(key)) {
|
|
1330
|
+
this.map.delete(key);
|
|
1331
|
+
}
|
|
1332
|
+
this.map.set(key, val);
|
|
1333
|
+
if (this.map.size > this.limit) {
|
|
1334
|
+
let evicted = false;
|
|
1335
|
+
for (const k of this.map.keys()) {
|
|
1336
|
+
if (!this._pinned.has(k)) {
|
|
1337
|
+
this.map.delete(k);
|
|
1338
|
+
evicted = true;
|
|
1339
|
+
break;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
if (!evicted && !this._warnedOverflow) {
|
|
1343
|
+
this._warnedOverflow = true;
|
|
1344
|
+
console.warn(
|
|
1345
|
+
`[LruCache] limit (${this.limit}) exceeded with every entry pinned \u2014 growing past limit instead of evicting/crashing. This usually means too many draft/unsynced records are open at once.`
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
pin(key) {
|
|
1351
|
+
this._pinned.add(key);
|
|
1352
|
+
}
|
|
1353
|
+
unpin(key) {
|
|
1354
|
+
this._pinned.delete(key);
|
|
1355
|
+
}
|
|
1356
|
+
has(key) {
|
|
1357
|
+
return this.map.has(key);
|
|
1358
|
+
}
|
|
1359
|
+
delete(key) {
|
|
1360
|
+
this.map.delete(key);
|
|
1361
|
+
}
|
|
1362
|
+
clear() {
|
|
1363
|
+
this.map.clear();
|
|
1364
|
+
}
|
|
1365
|
+
keys() {
|
|
1366
|
+
return this.map.keys();
|
|
1367
|
+
}
|
|
1368
|
+
values() {
|
|
1369
|
+
return this.map.values();
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
var DEFAULT_CACHE_LIMIT = 1e4;
|
|
1373
|
+
var dbConfig = {
|
|
1374
|
+
cacheLimit: DEFAULT_CACHE_LIMIT
|
|
1375
|
+
};
|
|
1376
|
+
var memory = /* @__PURE__ */ new Map();
|
|
1377
|
+
var configureDb = (opts) => {
|
|
1378
|
+
if (opts.cacheLimit && opts.cacheLimit > 0) {
|
|
1379
|
+
dbConfig.cacheLimit = opts.cacheLimit;
|
|
1380
|
+
for (const cache of memory.values()) {
|
|
1381
|
+
cache.limit = opts.cacheLimit;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
};
|
|
1385
|
+
var cacheFor = (objectType) => {
|
|
1386
|
+
let cache = memory.get(objectType);
|
|
1387
|
+
if (!cache) {
|
|
1388
|
+
cache = new LruCache(dbConfig.cacheLimit);
|
|
1389
|
+
memory.set(objectType, cache);
|
|
1390
|
+
}
|
|
1391
|
+
return cache;
|
|
1392
|
+
};
|
|
1393
|
+
var clear = () => {
|
|
1394
|
+
memory.clear();
|
|
1395
|
+
};
|
|
1396
|
+
var dump = () => {
|
|
1397
|
+
return memory;
|
|
1398
|
+
};
|
|
1399
|
+
function getRecordKey(wireId, creatorUsername) {
|
|
1400
|
+
if (isUserCreated(wireId)) {
|
|
1401
|
+
if (!creatorUsername) throw new Error("[models_v2] creatorUsername required for user-created records");
|
|
1402
|
+
return `${creatorUsername}:${wireId}`;
|
|
1403
|
+
}
|
|
1404
|
+
return `canonical:${wireId}`;
|
|
1405
|
+
}
|
|
1406
|
+
var hasRecord = (objectType, id, creatorUsername) => {
|
|
1407
|
+
if (isUserCreated(id) && !creatorUsername) return false;
|
|
1408
|
+
return cacheFor(objectType).has(getRecordKey(id, creatorUsername));
|
|
1409
|
+
};
|
|
1410
|
+
var getRecord = (objectType, id, creatorUsername) => {
|
|
1411
|
+
const key = getRecordKey(id, creatorUsername);
|
|
1412
|
+
const record = cacheFor(objectType).get(key);
|
|
1413
|
+
if (typeof record === "undefined") {
|
|
1414
|
+
throw new Error(`cannot find ${objectType} with id ${id} (evicted or never loaded \u2014 use LoadAsync)`);
|
|
1415
|
+
}
|
|
1416
|
+
return record;
|
|
1417
|
+
};
|
|
1418
|
+
var addRecord = (objectType, obj, creatorUsername) => {
|
|
1419
|
+
cacheFor(objectType).set(getRecordKey(obj.id, creatorUsername), obj);
|
|
1420
|
+
};
|
|
1421
|
+
var removeRecord = (objectType, id, creatorUsername) => {
|
|
1422
|
+
cacheFor(objectType).delete(getRecordKey(id, creatorUsername));
|
|
1423
|
+
};
|
|
1424
|
+
var pinRecord = (objectType, id, creatorUsername) => {
|
|
1425
|
+
cacheFor(objectType).pin(getRecordKey(id, creatorUsername));
|
|
1426
|
+
};
|
|
1427
|
+
var unpinRecord = (objectType, id, creatorUsername) => {
|
|
1428
|
+
cacheFor(objectType).unpin(getRecordKey(id, creatorUsername));
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
// src/models/localRecordTable.ts
|
|
1432
|
+
var LocalRecordTable = class {
|
|
1433
|
+
constructor() {
|
|
1434
|
+
this.db = null;
|
|
1435
|
+
this.instanceRemaps = new IDBInstanceRemapStore(this);
|
|
1436
|
+
}
|
|
1437
|
+
/** Called once at app startup, before any createNew() call — mirrors PatchInstance.initThread(). */
|
|
1438
|
+
init(db) {
|
|
1439
|
+
this.db = db;
|
|
1440
|
+
}
|
|
1441
|
+
get idb() {
|
|
1442
|
+
if (!this.db) throw new Error("[models_v2] LocalRecordTable not initialised \u2014 call localRecordTable.init(db) at startup");
|
|
1443
|
+
return this.db;
|
|
1444
|
+
}
|
|
1445
|
+
async put(entry) {
|
|
1446
|
+
return new Promise((resolve, reject) => {
|
|
1447
|
+
const tx = this.idb.transaction("localRecords", "readwrite");
|
|
1448
|
+
const store = tx.objectStore("localRecords");
|
|
1449
|
+
const req = store.put(entry);
|
|
1450
|
+
req.onsuccess = () => resolve();
|
|
1451
|
+
req.onerror = () => reject(req.error);
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
async putIfAbsent(entry) {
|
|
1455
|
+
return new Promise((resolve, reject) => {
|
|
1456
|
+
const tx = this.idb.transaction("localRecords", "readwrite");
|
|
1457
|
+
tx.onabort = () => reject(tx.error || new Error("Transaction aborted"));
|
|
1458
|
+
tx.onerror = () => reject(tx.error);
|
|
1459
|
+
const store = tx.objectStore("localRecords");
|
|
1460
|
+
const getReq = store.get([entry.creatorUsername, entry.wireId]);
|
|
1461
|
+
getReq.onsuccess = () => {
|
|
1462
|
+
if (!getReq.result) {
|
|
1463
|
+
const addReq = store.add(entry);
|
|
1464
|
+
addReq.onsuccess = () => resolve();
|
|
1465
|
+
addReq.onerror = () => reject(addReq.error);
|
|
1466
|
+
} else {
|
|
1467
|
+
resolve();
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
getReq.onerror = () => reject(getReq.error);
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
async get(creatorUsername, wireId) {
|
|
1474
|
+
return new Promise((resolve, reject) => {
|
|
1475
|
+
const tx = this.idb.transaction("localRecords", "readonly");
|
|
1476
|
+
const store = tx.objectStore("localRecords");
|
|
1477
|
+
const req = store.get([creatorUsername, wireId]);
|
|
1478
|
+
req.onsuccess = () => resolve(req.result);
|
|
1479
|
+
req.onerror = () => reject(req.error);
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
async getByCreator(creatorUsername) {
|
|
1483
|
+
return new Promise((resolve, reject) => {
|
|
1484
|
+
const tx = this.idb.transaction("localRecords", "readonly");
|
|
1485
|
+
const store = tx.objectStore("localRecords");
|
|
1486
|
+
const index = store.index("byCreator");
|
|
1487
|
+
const req = index.getAll(creatorUsername);
|
|
1488
|
+
req.onsuccess = () => resolve(req.result);
|
|
1489
|
+
req.onerror = () => reject(req.error);
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
async setStatus(creatorUsername, wireId, status) {
|
|
1493
|
+
return new Promise((resolve, reject) => {
|
|
1494
|
+
const tx = this.idb.transaction("localRecords", "readwrite");
|
|
1495
|
+
const store = tx.objectStore("localRecords");
|
|
1496
|
+
const getReq = store.get([creatorUsername, wireId]);
|
|
1497
|
+
getReq.onsuccess = () => {
|
|
1498
|
+
if (!getReq.result) {
|
|
1499
|
+
reject(new Error(`LocalRecordEntry not found: ${creatorUsername}:${wireId}`));
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
const entry = getReq.result;
|
|
1503
|
+
entry.status = status;
|
|
1504
|
+
const putReq = store.put(entry);
|
|
1505
|
+
putReq.onsuccess = () => resolve();
|
|
1506
|
+
putReq.onerror = () => reject(putReq.error);
|
|
1507
|
+
};
|
|
1508
|
+
getReq.onerror = () => reject(getReq.error);
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
async setCanonicalId(creatorUsername, wireId, canonicalId) {
|
|
1512
|
+
return new Promise((resolve, reject) => {
|
|
1513
|
+
const tx = this.idb.transaction("localRecords", "readwrite");
|
|
1514
|
+
const store = tx.objectStore("localRecords");
|
|
1515
|
+
const getReq = store.get([creatorUsername, wireId]);
|
|
1516
|
+
getReq.onsuccess = () => {
|
|
1517
|
+
if (!getReq.result) {
|
|
1518
|
+
reject(new Error(`LocalRecordEntry not found: ${creatorUsername}:${wireId}`));
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
const entry = getReq.result;
|
|
1522
|
+
entry.canonicalId = canonicalId;
|
|
1523
|
+
const putReq = store.put(entry);
|
|
1524
|
+
putReq.onsuccess = () => resolve();
|
|
1525
|
+
putReq.onerror = () => reject(putReq.error);
|
|
1526
|
+
};
|
|
1527
|
+
getReq.onerror = () => reject(getReq.error);
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
var IDBInstanceRemapStore = class {
|
|
1532
|
+
constructor(table) {
|
|
1533
|
+
this.table = table;
|
|
1534
|
+
}
|
|
1535
|
+
async get(objectId, langId, creatorUsername, originalIndex) {
|
|
1536
|
+
return new Promise((resolve, reject) => {
|
|
1537
|
+
const db = this.table.idb;
|
|
1538
|
+
const tx = db.transaction(instanceRemapsStoreName, "readonly");
|
|
1539
|
+
const store = tx.objectStore(instanceRemapsStoreName);
|
|
1540
|
+
const req = store.get([creatorUsername, objectId, langId, originalIndex]);
|
|
1541
|
+
req.onsuccess = () => resolve(req.result?.realIndex);
|
|
1542
|
+
req.onerror = () => reject(req.error);
|
|
1543
|
+
});
|
|
1544
|
+
}
|
|
1545
|
+
async put(objectId, langId, creatorUsername, originalIndex, realIndex) {
|
|
1546
|
+
return new Promise((resolve, reject) => {
|
|
1547
|
+
const db = this.table.idb;
|
|
1548
|
+
const tx = db.transaction(instanceRemapsStoreName, "readwrite");
|
|
1549
|
+
const store = tx.objectStore(instanceRemapsStoreName);
|
|
1550
|
+
const req = store.put({ creatorUsername, objectId, langId, originalIndex, realIndex });
|
|
1551
|
+
req.onsuccess = () => resolve();
|
|
1552
|
+
req.onerror = () => reject(req.error);
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
var localRecordTable = new LocalRecordTable();
|
|
1557
|
+
|
|
1558
|
+
// src/models/enriched-index.ts
|
|
1559
|
+
var SIDECAR_MAGIC = 1146113329;
|
|
1560
|
+
var SIDECAR_FORMAT_VERSION = 2;
|
|
1561
|
+
var columnTypeForBits = (bits) => {
|
|
1562
|
+
if (bits <= 0) return 3 /* NullableString */;
|
|
1563
|
+
if (bits <= 8) return 1 /* Uint8 */;
|
|
1564
|
+
if (bits <= 16) return 2 /* Uint16 */;
|
|
1565
|
+
return 6 /* Uint32 */;
|
|
1566
|
+
};
|
|
1567
|
+
var instanceSpecFromFields = (fields, fieldLayouts) => {
|
|
1568
|
+
return fields.map((f, idx) => {
|
|
1569
|
+
if (f.type === "string") return { name: f.name, type: 3 /* NullableString */ };
|
|
1570
|
+
if (f.type === "boolean") return { name: f.name, type: 7 /* Bool */ };
|
|
1571
|
+
const bits = fieldLayouts?.[idx]?.bits ?? f.bits ?? 32;
|
|
1572
|
+
return { name: f.name, type: columnTypeForBits(bits) };
|
|
1573
|
+
});
|
|
1574
|
+
};
|
|
1575
|
+
var IS_DEFAULT_SPEC = { name: "isDefault", type: 7 /* Bool */ };
|
|
1576
|
+
var textDecoder = new TextDecoder();
|
|
1577
|
+
var textEncoder = new TextEncoder();
|
|
1578
|
+
var extractRecordCols = (parsed, index) => {
|
|
1579
|
+
const sliceCol = (data) => Array.isArray(data) ? [data[index] ?? null] : data.slice(index, index + 1);
|
|
1580
|
+
if (parsed.header.sidecarType === 2 /* Provenance */) {
|
|
1581
|
+
const fields = {};
|
|
1582
|
+
let ids;
|
|
1583
|
+
for (const [name, data] of parsed.columns) {
|
|
1584
|
+
if (name === "ids") ids = sliceCol(data);
|
|
1585
|
+
else fields[name] = sliceCol(data);
|
|
1586
|
+
}
|
|
1587
|
+
return { ids, fields };
|
|
1588
|
+
}
|
|
1589
|
+
const cols = {};
|
|
1590
|
+
for (const [name, data] of parsed.columns) {
|
|
1591
|
+
cols[name] = sliceCol(data);
|
|
1592
|
+
}
|
|
1593
|
+
if (parsed.relations) for (const [name, data] of parsed.relations) cols[name] = [data[index] ?? []];
|
|
1594
|
+
if (parsed.authorIds) cols["authorIds"] = [parsed.authorIds[index] ?? []];
|
|
1595
|
+
if (parsed.instances) cols["instances"] = [parsed.instances[index] ?? []];
|
|
1596
|
+
return cols;
|
|
1597
|
+
};
|
|
1598
|
+
var Writer = class {
|
|
1599
|
+
constructor() {
|
|
1600
|
+
this.chunks = [];
|
|
1601
|
+
}
|
|
1602
|
+
u8(v) {
|
|
1603
|
+
this.chunks.push(new Uint8Array([v & 255]));
|
|
1604
|
+
}
|
|
1605
|
+
u16(v) {
|
|
1606
|
+
const b = new Uint8Array(2);
|
|
1607
|
+
new DataView(b.buffer).setUint16(0, v);
|
|
1608
|
+
this.chunks.push(b);
|
|
1609
|
+
}
|
|
1610
|
+
u24(v) {
|
|
1611
|
+
const b = new Uint8Array(3);
|
|
1612
|
+
b[0] = v >>> 16 & 255;
|
|
1613
|
+
b[1] = v >>> 8 & 255;
|
|
1614
|
+
b[2] = v & 255;
|
|
1615
|
+
this.chunks.push(b);
|
|
1616
|
+
}
|
|
1617
|
+
u32(v) {
|
|
1618
|
+
const b = new Uint8Array(4);
|
|
1619
|
+
new DataView(b.buffer).setUint32(0, v >>> 0);
|
|
1620
|
+
this.chunks.push(b);
|
|
1621
|
+
}
|
|
1622
|
+
bytes(v) {
|
|
1623
|
+
this.chunks.push(v);
|
|
1624
|
+
}
|
|
1625
|
+
nullableString(v) {
|
|
1626
|
+
if (v === null) {
|
|
1627
|
+
this.u8(0);
|
|
1628
|
+
return;
|
|
1629
|
+
}
|
|
1630
|
+
this.u8(1);
|
|
1631
|
+
const encoded = textEncoder.encode(v);
|
|
1632
|
+
this.u16(encoded.length);
|
|
1633
|
+
this.bytes(encoded);
|
|
1634
|
+
}
|
|
1635
|
+
toBuffer() {
|
|
1636
|
+
const total = this.chunks.reduce((acc, c) => acc + c.length, 0);
|
|
1637
|
+
const out = new Uint8Array(total);
|
|
1638
|
+
let offset = 0;
|
|
1639
|
+
for (const c of this.chunks) {
|
|
1640
|
+
out.set(c, offset);
|
|
1641
|
+
offset += c.length;
|
|
1642
|
+
}
|
|
1643
|
+
return out.buffer;
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
var collectRelations = (input) => {
|
|
1647
|
+
const list = [...input.relations ?? []];
|
|
1648
|
+
if (input.authorIds && !list.some((r) => r.name === "authors")) {
|
|
1649
|
+
list.push({ name: "authors", data: input.authorIds });
|
|
1650
|
+
}
|
|
1651
|
+
return list;
|
|
1652
|
+
};
|
|
1653
|
+
var writeFieldValue = (w, type, value) => {
|
|
1654
|
+
switch (type) {
|
|
1655
|
+
case 1 /* Uint8 */:
|
|
1656
|
+
w.u8(value ?? 0);
|
|
1657
|
+
break;
|
|
1658
|
+
case 2 /* Uint16 */:
|
|
1659
|
+
w.u16(value ?? 0);
|
|
1660
|
+
break;
|
|
1661
|
+
case 6 /* Uint32 */:
|
|
1662
|
+
w.u32(value ?? 0);
|
|
1663
|
+
break;
|
|
1664
|
+
case 7 /* Bool */:
|
|
1665
|
+
w.u8(value ? 1 : 0);
|
|
1666
|
+
break;
|
|
1667
|
+
case 3 /* NullableString */:
|
|
1668
|
+
w.nullableString(value ?? null);
|
|
1669
|
+
break;
|
|
1670
|
+
default:
|
|
1671
|
+
throw new Error(`Unsupported instance field type 0x${type.toString(16)}`);
|
|
1672
|
+
}
|
|
1673
|
+
};
|
|
1674
|
+
var writeInstanceDescriptor = (w, spec) => {
|
|
1675
|
+
if (spec.length > 255) throw new Error("Too many instance fields (max 255)");
|
|
1676
|
+
w.u8(spec.length);
|
|
1677
|
+
for (const field of spec) {
|
|
1678
|
+
w.u8(field.type);
|
|
1679
|
+
const nameBytes = textEncoder.encode(field.name);
|
|
1680
|
+
w.u8(nameBytes.length);
|
|
1681
|
+
w.bytes(nameBytes);
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
var writeSidecar = (input) => {
|
|
1685
|
+
const w = new Writer();
|
|
1686
|
+
w.u32(SIDECAR_MAGIC);
|
|
1687
|
+
w.u8(SIDECAR_FORMAT_VERSION);
|
|
1688
|
+
w.u24(input.recordCount);
|
|
1689
|
+
w.u8(input.columns.length);
|
|
1690
|
+
w.u8(input.sidecarType);
|
|
1691
|
+
for (const col of input.columns) {
|
|
1692
|
+
w.u8(col.type);
|
|
1693
|
+
const nameBytes = textEncoder.encode(col.name);
|
|
1694
|
+
w.u8(nameBytes.length);
|
|
1695
|
+
w.bytes(nameBytes);
|
|
1696
|
+
const data = col.data;
|
|
1697
|
+
for (let i = 0; i < input.recordCount; i++) {
|
|
1698
|
+
switch (col.type) {
|
|
1699
|
+
case 1 /* Uint8 */:
|
|
1700
|
+
w.u8(data[i] ?? 0);
|
|
1701
|
+
break;
|
|
1702
|
+
case 2 /* Uint16 */:
|
|
1703
|
+
w.u16(data[i] ?? 0);
|
|
1704
|
+
break;
|
|
1705
|
+
case 6 /* Uint32 */:
|
|
1706
|
+
w.u32(data[i] ?? 0);
|
|
1707
|
+
break;
|
|
1708
|
+
case 7 /* Bool */:
|
|
1709
|
+
w.u8(data[i] ? 1 : 0);
|
|
1710
|
+
break;
|
|
1711
|
+
case 3 /* NullableString */:
|
|
1712
|
+
w.nullableString(data[i] ?? null);
|
|
1713
|
+
break;
|
|
1714
|
+
default:
|
|
1715
|
+
throw new Error(`Unsupported column type 0x${col.type.toString(16)}`);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
if (input.sidecarType === 1 /* Extended */) {
|
|
1720
|
+
const relations = collectRelations(input);
|
|
1721
|
+
w.u8(relations.length);
|
|
1722
|
+
for (const rel of relations) {
|
|
1723
|
+
const nameBytes = textEncoder.encode(rel.name);
|
|
1724
|
+
w.u8(nameBytes.length);
|
|
1725
|
+
w.bytes(nameBytes);
|
|
1726
|
+
}
|
|
1727
|
+
for (let i = 0; i < input.recordCount; i++) {
|
|
1728
|
+
for (const rel of relations) {
|
|
1729
|
+
const uids = rel.data[i] ?? [];
|
|
1730
|
+
w.u16(uids.length);
|
|
1731
|
+
for (const u of uids) w.u24(u);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
const declared = input.instanceFields ?? [];
|
|
1735
|
+
if ((input.instances?.length ?? 0) > 0 && declared.length === 0) {
|
|
1736
|
+
throw new Error("writeSidecar: instances provided without instanceFields spec");
|
|
1737
|
+
}
|
|
1738
|
+
const spec = declared.some((f) => f.name === IS_DEFAULT_SPEC.name) ? declared : [...declared, IS_DEFAULT_SPEC];
|
|
1739
|
+
writeInstanceDescriptor(w, spec);
|
|
1740
|
+
const instances = input.instances ?? [];
|
|
1741
|
+
for (let i = 0; i < input.recordCount; i++) {
|
|
1742
|
+
const list = instances[i] ?? [];
|
|
1743
|
+
w.u16(list.length);
|
|
1744
|
+
for (const inst of list) {
|
|
1745
|
+
for (const field of spec) {
|
|
1746
|
+
writeFieldValue(w, field.type, inst[field.name]);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
return w.toBuffer();
|
|
1752
|
+
};
|
|
1753
|
+
|
|
1754
|
+
// src/models/serializer.ts
|
|
1755
|
+
var capitalize = (name) => name.charAt(0).toUpperCase() + name.slice(1);
|
|
1756
|
+
var colName = (name, type) => type === "string" && !name.endsWith("s") ? `${name}s` : name;
|
|
1757
|
+
var propBits = (prop, layout) => {
|
|
1758
|
+
const fromLayout = layout.props[prop.propId]?.bits;
|
|
1759
|
+
if (typeof fromLayout === "number" && fromLayout > 0) return fromLayout;
|
|
1760
|
+
if (prop.type === "boolean") return 1;
|
|
1761
|
+
return prop.bits ?? 32;
|
|
1762
|
+
};
|
|
1763
|
+
var instanceFieldBits = (field, index, objectId, layout) => {
|
|
1764
|
+
const propId = layout.instanceFields?.[objectId]?.[index];
|
|
1765
|
+
const fromLayout = typeof propId === "number" ? layout.props[propId]?.bits : void 0;
|
|
1766
|
+
if (typeof fromLayout === "number" && fromLayout > 0) return fromLayout;
|
|
1767
|
+
if (field.type === "boolean") return 1;
|
|
1768
|
+
return field.bits ?? 32;
|
|
1769
|
+
};
|
|
1770
|
+
var relationColName = (rel) => rel.name === "authors" ? "authorIds" : rel.name;
|
|
1771
|
+
var extractTypedArray = (bits, values) => {
|
|
1772
|
+
if (bits <= 8) return Uint8Array.from(values);
|
|
1773
|
+
if (bits <= 16) return Uint16Array.from(values);
|
|
1774
|
+
return Uint32Array.from(values);
|
|
1775
|
+
};
|
|
1776
|
+
function commonSerializeSlim(schema4, records, layout) {
|
|
1777
|
+
const uids = records.map((r) => r.id);
|
|
1778
|
+
const columns = [
|
|
1779
|
+
{ name: "ids", type: 6 /* Uint32 */, data: Uint32Array.from(uids) },
|
|
1780
|
+
{ name: "titles", type: 3 /* NullableString */, data: records.map((r) => r.title) },
|
|
1781
|
+
{ name: "originalLangs", type: 3 /* NullableString */, data: records.map((r) => r.originalLang) },
|
|
1782
|
+
{ name: "previewTxIds", type: 3 /* NullableString */, data: records.map((r) => r.previewTxId) },
|
|
1783
|
+
{ name: "ageGradeBands", type: 1 /* Uint8 */, data: Uint8Array.from(records.map((r) => r.ageGradeBand)) },
|
|
1784
|
+
{ name: "safes", type: 1 /* Uint8 */, data: Uint8Array.from(records.map((r) => r.safe ? 1 : 0)) },
|
|
1785
|
+
{ name: "deleteds", type: 1 /* Uint8 */, data: Uint8Array.from(records.map((r) => r.deleted ? 1 : 0)) }
|
|
1786
|
+
];
|
|
1787
|
+
for (const prop of schema4.props.filter((p) => p.source === "slim")) {
|
|
1788
|
+
const name = colName(prop.name, prop.type);
|
|
1789
|
+
if (prop.type === "string") {
|
|
1790
|
+
columns.push({ name, type: 3 /* NullableString */, data: records.map((r) => r[prop.name]) });
|
|
1791
|
+
} else if (prop.type === "boolean") {
|
|
1792
|
+
columns.push({ name, type: 1 /* Uint8 */, data: Uint8Array.from(records.map((r) => r[prop.name] ? 1 : 0)) });
|
|
1793
|
+
} else {
|
|
1794
|
+
const bits = propBits(prop, layout);
|
|
1795
|
+
columns.push({ name, type: columnTypeForBits(bits), data: extractTypedArray(bits, records.map((r) => r[prop.name])) });
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
if (schema4.multipleInstances) {
|
|
1799
|
+
for (let i = 0; i < schema4.instanceFields.length; i++) {
|
|
1800
|
+
const field = schema4.instanceFields[i];
|
|
1801
|
+
const capField = capitalize(field.name);
|
|
1802
|
+
const capName = colName(capField, field.type);
|
|
1803
|
+
const values = records.map((r) => r[`default${capField}`]);
|
|
1804
|
+
if (field.type === "string") {
|
|
1805
|
+
columns.push({ name: `default${capName}`, type: 3 /* NullableString */, data: values });
|
|
1806
|
+
} else if (field.type === "boolean") {
|
|
1807
|
+
columns.push({ name: `default${capName}`, type: 1 /* Uint8 */, data: Uint8Array.from(values.map((v) => v ? 1 : 0)) });
|
|
1808
|
+
} else {
|
|
1809
|
+
const bits = instanceFieldBits(field, i, schema4.objectId, layout);
|
|
1810
|
+
columns.push({ name: `default${capName}`, type: columnTypeForBits(bits), data: extractTypedArray(bits, values) });
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
const input = {
|
|
1815
|
+
sidecarType: 0 /* Slim */,
|
|
1816
|
+
recordCount: records.length,
|
|
1817
|
+
columns
|
|
1818
|
+
};
|
|
1819
|
+
return writeSidecar(input);
|
|
1820
|
+
}
|
|
1821
|
+
function commonSerializeExtended(schema4, records, layout) {
|
|
1822
|
+
const uids = records.map((r) => r.id);
|
|
1823
|
+
const columns = [
|
|
1824
|
+
{ name: "ids", type: 6 /* Uint32 */, data: Uint32Array.from(uids) },
|
|
1825
|
+
{ name: "descriptions", type: 3 /* NullableString */, data: records.map((r) => r.description) }
|
|
1826
|
+
];
|
|
1827
|
+
for (const prop of schema4.props.filter((p) => p.source === "extended")) {
|
|
1828
|
+
const name = colName(prop.name, prop.type);
|
|
1829
|
+
if (prop.type === "string") {
|
|
1830
|
+
columns.push({ name, type: 3 /* NullableString */, data: records.map((r) => r[prop.name]) });
|
|
1831
|
+
} else if (prop.type === "boolean") {
|
|
1832
|
+
columns.push({ name, type: 1 /* Uint8 */, data: Uint8Array.from(records.map((r) => r[prop.name] ? 1 : 0)) });
|
|
1833
|
+
} else {
|
|
1834
|
+
const bits = propBits(prop, layout);
|
|
1835
|
+
columns.push({ name, type: columnTypeForBits(bits), data: extractTypedArray(bits, records.map((r) => r[prop.name])) });
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
const hasRelations = schema4.relations.filter((r) => r.direction === "has");
|
|
1839
|
+
const relations = hasRelations.map((rel) => ({
|
|
1840
|
+
name: rel.name,
|
|
1841
|
+
data: records.map((r) => r[relationColName(rel)])
|
|
1842
|
+
}));
|
|
1843
|
+
const input = {
|
|
1844
|
+
sidecarType: 1 /* Extended */,
|
|
1845
|
+
recordCount: records.length,
|
|
1846
|
+
columns,
|
|
1847
|
+
...relations.length > 0 && { relations }
|
|
1848
|
+
};
|
|
1849
|
+
if (schema4.multipleInstances) {
|
|
1850
|
+
input.instanceFields = instanceSpecFromFields(schema4.instanceFields);
|
|
1851
|
+
input.instances = records.map((r) => r.instances);
|
|
1852
|
+
}
|
|
1853
|
+
return writeSidecar(input);
|
|
1854
|
+
}
|
|
1855
|
+
function commonSerializeProv(schema4, records) {
|
|
1856
|
+
const input = {
|
|
1857
|
+
sidecarType: 2 /* Provenance */,
|
|
1858
|
+
recordCount: records.length,
|
|
1859
|
+
columns: [
|
|
1860
|
+
{ name: "ids", type: 6 /* Uint32 */, data: Uint32Array.from(records.map((r) => r.id)) }
|
|
1861
|
+
]
|
|
1862
|
+
};
|
|
1863
|
+
return writeSidecar(input);
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
// src/models/registry.ts
|
|
1867
|
+
var relationColName2 = (rel) => rel.name === "authors" ? "authorIds" : rel.name;
|
|
1868
|
+
var SchemaRegistry = class _SchemaRegistry {
|
|
1869
|
+
constructor() {
|
|
1870
|
+
this.schemas = /* @__PURE__ */ new Map();
|
|
1871
|
+
this.byName = /* @__PURE__ */ new Map();
|
|
1872
|
+
}
|
|
1873
|
+
static getInstance() {
|
|
1874
|
+
if (!_SchemaRegistry.instance) {
|
|
1875
|
+
_SchemaRegistry.instance = new _SchemaRegistry();
|
|
1876
|
+
}
|
|
1877
|
+
return _SchemaRegistry.instance;
|
|
1878
|
+
}
|
|
1879
|
+
register(schema4) {
|
|
1880
|
+
this.schemas.set(schema4.objectId, schema4);
|
|
1881
|
+
this.byName.set(schema4.name, schema4);
|
|
1882
|
+
}
|
|
1883
|
+
get(id) {
|
|
1884
|
+
const schema4 = this.schemas.get(id);
|
|
1885
|
+
if (!schema4) {
|
|
1886
|
+
console.warn(`[SchemaRegistry] No schema registered for type ID ${id}. Returning generic placeholder.`);
|
|
1887
|
+
return { name: "Generic", typePrefix: "XX", objectId: id, multipleInstances: false, props: [], instanceFields: [], relations: [] };
|
|
1888
|
+
}
|
|
1889
|
+
return schema4;
|
|
1890
|
+
}
|
|
1891
|
+
/** Lookup by model name (relation targetType resolution). */
|
|
1892
|
+
getByName(name) {
|
|
1893
|
+
return this.byName.get(name);
|
|
1894
|
+
}
|
|
1895
|
+
clear() {
|
|
1896
|
+
this.schemas.clear();
|
|
1897
|
+
this.byName.clear();
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
var Registry = SchemaRegistry.getInstance();
|
|
1901
|
+
|
|
1902
|
+
// src/models/orm.ts
|
|
1903
|
+
var _userLang = null;
|
|
1904
|
+
var _commonLang = "eng";
|
|
1905
|
+
var _defaultProvenance = void 0;
|
|
1906
|
+
var Config = {
|
|
1907
|
+
get userLang() {
|
|
1908
|
+
if (_userLang === null) {
|
|
1909
|
+
throw new Error("[models_v2] Default language not set! Call setDefaultLanguage() before using models.");
|
|
1910
|
+
}
|
|
1911
|
+
return _userLang;
|
|
1912
|
+
},
|
|
1913
|
+
get commonLang() {
|
|
1914
|
+
return _commonLang;
|
|
1915
|
+
},
|
|
1916
|
+
get defaultProvenance() {
|
|
1917
|
+
return _defaultProvenance;
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
function setDefaultLanguage(lang) {
|
|
1921
|
+
_userLang = lang;
|
|
1922
|
+
}
|
|
1923
|
+
var TITLE_PROP = 0;
|
|
1924
|
+
var DESCRIPTION_PROP = 1;
|
|
1925
|
+
var ORIGINAL_LANG_PROP = 2;
|
|
1926
|
+
var AGE_GRADE_BAND_PROP = 3;
|
|
1927
|
+
var PREVIEW_TX_ID_PROP = 4;
|
|
1928
|
+
var SAFE_PROP = 5;
|
|
1929
|
+
var DELETED_PROP = 6;
|
|
1930
|
+
var LIFECYCLE_STATUS_PROP = 7;
|
|
1931
|
+
function serializeMapOfSets(map) {
|
|
1932
|
+
return Array.from(map.entries()).map(([key, value]) => [key, Array.from(value.values())]);
|
|
1933
|
+
}
|
|
1934
|
+
function serializeMapOfMaps(mapOfMaps) {
|
|
1935
|
+
return Array.from(mapOfMaps, ([key, innerMap]) => [key, Array.from(innerMap.entries())]);
|
|
1936
|
+
}
|
|
1937
|
+
var inflateOrmJson = (v2) => {
|
|
1938
|
+
const [id, hasArr, inArr, numArr, boolArr, strArr, instArr] = v2;
|
|
1939
|
+
return [
|
|
1940
|
+
id,
|
|
1941
|
+
new Map(hasArr.map(([rid, set]) => [rid, new Set(set)])),
|
|
1942
|
+
new Map(inArr.map(([rid, set]) => [rid, new Set(set)])),
|
|
1943
|
+
new Map(numArr.map(([pid, langs]) => [pid, new Map(langs)])),
|
|
1944
|
+
new Map(boolArr.map(([pid, langs]) => [pid, new Map(langs)])),
|
|
1945
|
+
new Map(strArr.map(([pid, langs]) => [pid, new Map(langs)])),
|
|
1946
|
+
new Map(instArr)
|
|
1947
|
+
];
|
|
1948
|
+
};
|
|
1949
|
+
var warnedLangs = /* @__PURE__ */ new Set();
|
|
1950
|
+
var resolveLangValue = (values, lang) => {
|
|
1951
|
+
if (!values) return void 0;
|
|
1952
|
+
if (values.has(lang)) return values.get(lang);
|
|
1953
|
+
if (values.has(LANG_AGNOSTIC)) return values.get(LANG_AGNOSTIC);
|
|
1954
|
+
if (values.size === 1) return values.values().next().value;
|
|
1955
|
+
return void 0;
|
|
1956
|
+
};
|
|
1957
|
+
var Orm = class extends Stats {
|
|
1958
|
+
constructor(objectType, json, creatorUsername) {
|
|
1959
|
+
const hydrated = json[1] instanceof Map ? json : inflateOrmJson(json);
|
|
1960
|
+
super(hydrated[0], objectType);
|
|
1961
|
+
this._boolValues = /* @__PURE__ */ new Map();
|
|
1962
|
+
this._stringValues = /* @__PURE__ */ new Map();
|
|
1963
|
+
this._numberValues = /* @__PURE__ */ new Map();
|
|
1964
|
+
this._has = /* @__PURE__ */ new Map();
|
|
1965
|
+
this._in = /* @__PURE__ */ new Map();
|
|
1966
|
+
/** lang -> instance array (BookInstanceData structs, not ORM objects). */
|
|
1967
|
+
this._instances = /* @__PURE__ */ new Map();
|
|
1968
|
+
/** lang -> propId -> provenance code (2-bit: unset/AI/human/consensus). */
|
|
1969
|
+
this._provenance = /* @__PURE__ */ new Map();
|
|
1970
|
+
this._id = hydrated[0];
|
|
1971
|
+
this._creatorUsername = creatorUsername;
|
|
1972
|
+
this._has = hydrated[1];
|
|
1973
|
+
this._in = hydrated[2];
|
|
1974
|
+
this._numberValues = hydrated[3];
|
|
1975
|
+
this._boolValues = hydrated[4];
|
|
1976
|
+
this._stringValues = hydrated[5];
|
|
1977
|
+
this._instances = hydrated[6] ?? /* @__PURE__ */ new Map();
|
|
1978
|
+
this.schema = Registry.get(objectType);
|
|
1979
|
+
for (const { relationId, direction } of this.schema.relations ?? []) {
|
|
1980
|
+
const target = direction === "has" ? this._has : this._in;
|
|
1981
|
+
if (!target.has(relationId)) {
|
|
1982
|
+
target.set(relationId, /* @__PURE__ */ new Set());
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
for (const pid of [TITLE_PROP, DESCRIPTION_PROP, ORIGINAL_LANG_PROP, PREVIEW_TX_ID_PROP]) {
|
|
1986
|
+
if (!this._stringValues.has(pid)) {
|
|
1987
|
+
this._stringValues.set(pid, /* @__PURE__ */ new Map());
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
if (!this._boolValues.has(SAFE_PROP)) {
|
|
1991
|
+
this._boolValues.set(SAFE_PROP, /* @__PURE__ */ new Map([[LANG_AGNOSTIC, true]]));
|
|
1992
|
+
}
|
|
1993
|
+
if (!this._boolValues.has(DELETED_PROP)) {
|
|
1994
|
+
this._boolValues.set(DELETED_PROP, /* @__PURE__ */ new Map([[LANG_AGNOSTIC, false]]));
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
static createNewRequest(id) {
|
|
1998
|
+
return [
|
|
1999
|
+
id,
|
|
2000
|
+
/* @__PURE__ */ new Map(),
|
|
2001
|
+
/* @__PURE__ */ new Map(),
|
|
2002
|
+
/* @__PURE__ */ new Map(),
|
|
2003
|
+
/* @__PURE__ */ new Map(),
|
|
2004
|
+
/* @__PURE__ */ new Map(),
|
|
2005
|
+
/* @__PURE__ */ new Map()
|
|
2006
|
+
];
|
|
2007
|
+
}
|
|
2008
|
+
static async createNewRecord(uidFactory, creatorUsername) {
|
|
2009
|
+
const { wireId, localId } = await uidFactory.next();
|
|
2010
|
+
const op = {
|
|
2011
|
+
operation: PatchOperation.CreateRecord,
|
|
2012
|
+
objectType: this.type,
|
|
2013
|
+
objectId: wireId,
|
|
2014
|
+
langId: 0
|
|
2015
|
+
};
|
|
2016
|
+
PatchInstance.addPatch(op);
|
|
2017
|
+
const emptyJson = [
|
|
2018
|
+
wireId,
|
|
2019
|
+
/* @__PURE__ */ new Map(),
|
|
2020
|
+
/* @__PURE__ */ new Map(),
|
|
2021
|
+
/* @__PURE__ */ new Map(),
|
|
2022
|
+
/* @__PURE__ */ new Map(),
|
|
2023
|
+
/* @__PURE__ */ new Map(),
|
|
2024
|
+
/* @__PURE__ */ new Map()
|
|
2025
|
+
];
|
|
2026
|
+
const record = new this(emptyJson, creatorUsername);
|
|
2027
|
+
addRecord(this.type, record, creatorUsername);
|
|
2028
|
+
pinRecord(this.type, wireId, creatorUsername);
|
|
2029
|
+
await localRecordTable.putIfAbsent({
|
|
2030
|
+
wireId,
|
|
2031
|
+
creatorUsername,
|
|
2032
|
+
objectType: this.type,
|
|
2033
|
+
localId,
|
|
2034
|
+
createdAt: Date.now(),
|
|
2035
|
+
status: "active"
|
|
2036
|
+
});
|
|
2037
|
+
return record;
|
|
2038
|
+
}
|
|
2039
|
+
get creatorUsername() {
|
|
2040
|
+
if (!isUserCreated(this.id)) return "canonical";
|
|
2041
|
+
return this._creatorUsername ?? "";
|
|
2042
|
+
}
|
|
2043
|
+
toJSON() {
|
|
2044
|
+
return [
|
|
2045
|
+
this._id,
|
|
2046
|
+
serializeMapOfSets(this._has),
|
|
2047
|
+
serializeMapOfSets(this._in),
|
|
2048
|
+
serializeMapOfMaps(this._numberValues),
|
|
2049
|
+
serializeMapOfMaps(this._boolValues),
|
|
2050
|
+
serializeMapOfMaps(this._stringValues),
|
|
2051
|
+
Array.from(this._instances.entries())
|
|
2052
|
+
];
|
|
2053
|
+
}
|
|
2054
|
+
get id() {
|
|
2055
|
+
return this._id;
|
|
2056
|
+
}
|
|
2057
|
+
// ─── Language helpers ────────────────────────────────────────────────────
|
|
2058
|
+
langOf(langId) {
|
|
2059
|
+
return LANG_ID_DECODE[langId] ?? LANG_AGNOSTIC;
|
|
2060
|
+
}
|
|
2061
|
+
langIdOf(lang) {
|
|
2062
|
+
const l = lang ?? Config.userLang;
|
|
2063
|
+
const id = LANG_ID_ENCODE[l];
|
|
2064
|
+
if (id === void 0) {
|
|
2065
|
+
if (l !== LANG_AGNOSTIC && !warnedLangs.has(l)) {
|
|
2066
|
+
warnedLangs.add(l);
|
|
2067
|
+
console.warn(
|
|
2068
|
+
`[models_v2] Unknown language "${l}" \u2014 patches will land in the lang-agnostic slot (langId 0) and may collide with other unmapped languages. Append "${l}" to LANG_ID_ENCODE in db_schema_v2.`
|
|
2069
|
+
);
|
|
2070
|
+
}
|
|
2071
|
+
return 0;
|
|
2072
|
+
}
|
|
2073
|
+
return id;
|
|
2074
|
+
}
|
|
2075
|
+
// ─── Base props ──────────────────────────────────────────────────────────
|
|
2076
|
+
get title() {
|
|
2077
|
+
return this.getProp(TITLE_PROP) ?? "";
|
|
2078
|
+
}
|
|
2079
|
+
set title(value) {
|
|
2080
|
+
this.dispatchString(TITLE_PROP, value);
|
|
2081
|
+
}
|
|
2082
|
+
getTitle(lang) {
|
|
2083
|
+
return this.getProp(TITLE_PROP, lang) ?? "";
|
|
2084
|
+
}
|
|
2085
|
+
setTitle(value, lang) {
|
|
2086
|
+
this.dispatchString(TITLE_PROP, value, lang);
|
|
2087
|
+
}
|
|
2088
|
+
get description() {
|
|
2089
|
+
return this.getProp(DESCRIPTION_PROP) ?? "";
|
|
2090
|
+
}
|
|
2091
|
+
set description(value) {
|
|
2092
|
+
this.dispatchString(DESCRIPTION_PROP, value);
|
|
2093
|
+
}
|
|
2094
|
+
getDescription(lang) {
|
|
2095
|
+
return this.getProp(DESCRIPTION_PROP, lang) ?? "";
|
|
2096
|
+
}
|
|
2097
|
+
setDescription(value, lang) {
|
|
2098
|
+
this.dispatchString(DESCRIPTION_PROP, value, lang);
|
|
2099
|
+
}
|
|
2100
|
+
get originalLang() {
|
|
2101
|
+
return this.getProp(ORIGINAL_LANG_PROP) ?? "";
|
|
2102
|
+
}
|
|
2103
|
+
set originalLang(value) {
|
|
2104
|
+
this.dispatchString(ORIGINAL_LANG_PROP, value);
|
|
2105
|
+
}
|
|
2106
|
+
getOriginalLang(lang) {
|
|
2107
|
+
return this.getProp(ORIGINAL_LANG_PROP, lang) ?? "";
|
|
2108
|
+
}
|
|
2109
|
+
setOriginalLang(value, lang) {
|
|
2110
|
+
this.dispatchString(ORIGINAL_LANG_PROP, value, lang);
|
|
2111
|
+
}
|
|
2112
|
+
get ageGradeBand() {
|
|
2113
|
+
return this.getProp(AGE_GRADE_BAND_PROP) ?? 0;
|
|
2114
|
+
}
|
|
2115
|
+
set ageGradeBand(value) {
|
|
2116
|
+
this.dispatchNumber(AGE_GRADE_BAND_PROP, value);
|
|
2117
|
+
}
|
|
2118
|
+
get previewTxId() {
|
|
2119
|
+
return this.getProp(PREVIEW_TX_ID_PROP) ?? "";
|
|
2120
|
+
}
|
|
2121
|
+
set previewTxId(value) {
|
|
2122
|
+
this.dispatchString(PREVIEW_TX_ID_PROP, value);
|
|
2123
|
+
}
|
|
2124
|
+
get safe() {
|
|
2125
|
+
return this.getProp(SAFE_PROP) ?? true;
|
|
2126
|
+
}
|
|
2127
|
+
set safe(value) {
|
|
2128
|
+
this.dispatchNumber(SAFE_PROP, value ? 1 : 0);
|
|
2129
|
+
}
|
|
2130
|
+
get deleted() {
|
|
2131
|
+
return this.getProp(DELETED_PROP) ?? false;
|
|
2132
|
+
}
|
|
2133
|
+
set deleted(value) {
|
|
2134
|
+
this.dispatchNumber(DELETED_PROP, value ? 1 : 0);
|
|
2135
|
+
}
|
|
2136
|
+
get lifecycleStatus() {
|
|
2137
|
+
return this.getProp(LIFECYCLE_STATUS_PROP) ?? 0 /* Provisional */;
|
|
2138
|
+
}
|
|
2139
|
+
set lifecycleStatus(value) {
|
|
2140
|
+
if (!isUserCreated(this.id)) {
|
|
2141
|
+
throw new Error("lifecycleStatus can only be set on user-created provisional records");
|
|
2142
|
+
}
|
|
2143
|
+
if (!this._creatorUsername) throw new Error("Missing creatorUsername on provisional record");
|
|
2144
|
+
if (value < this.lifecycleStatus) {
|
|
2145
|
+
throw new Error(`lifecycleStatus is forward-only: cannot transition from ${this.lifecycleStatus} to ${value}`);
|
|
2146
|
+
}
|
|
2147
|
+
this.dispatchNumber(LIFECYCLE_STATUS_PROP, value, LANG_AGNOSTIC);
|
|
2148
|
+
}
|
|
2149
|
+
// ─── Patch dispatch (mutation entry points used by generated setters) ────
|
|
2150
|
+
dispatchString(propertyId, value, lang) {
|
|
2151
|
+
const op = {
|
|
2152
|
+
operation: PatchOperation.EditPropertyString,
|
|
2153
|
+
objectType: this.objectType,
|
|
2154
|
+
objectId: this.id,
|
|
2155
|
+
langId: this.langIdOf(lang),
|
|
2156
|
+
propertyId,
|
|
2157
|
+
value
|
|
2158
|
+
};
|
|
2159
|
+
this.patch(op);
|
|
2160
|
+
const targetLang = lang ?? Config.userLang;
|
|
2161
|
+
const prov = Config.defaultProvenance;
|
|
2162
|
+
if (prov !== void 0 && this.getProvenance(propertyId, targetLang) !== prov) {
|
|
2163
|
+
this.setProvenanceRaw(targetLang, propertyId, prov);
|
|
2164
|
+
}
|
|
2165
|
+
PatchInstance.addPatch(op);
|
|
2166
|
+
}
|
|
2167
|
+
dispatchNumber(propertyId, value, lang) {
|
|
2168
|
+
const op = {
|
|
2169
|
+
operation: PatchOperation.EditPropertyNumber,
|
|
2170
|
+
objectType: this.objectType,
|
|
2171
|
+
objectId: this.id,
|
|
2172
|
+
langId: this.langIdOf(lang),
|
|
2173
|
+
propertyId,
|
|
2174
|
+
value
|
|
2175
|
+
};
|
|
2176
|
+
this.patch(op);
|
|
2177
|
+
const targetLang = lang ?? Config.userLang;
|
|
2178
|
+
const prov = Config.defaultProvenance;
|
|
2179
|
+
if (prov !== void 0 && this.getProvenance(propertyId, targetLang) !== prov) {
|
|
2180
|
+
this.setProvenanceRaw(targetLang, propertyId, prov);
|
|
2181
|
+
}
|
|
2182
|
+
PatchInstance.addPatch(op);
|
|
2183
|
+
}
|
|
2184
|
+
dispatchRelation(relationId, action, targetId) {
|
|
2185
|
+
const op = {
|
|
2186
|
+
operation: PatchOperation.EditRelation,
|
|
2187
|
+
objectType: this.objectType,
|
|
2188
|
+
objectId: this.id,
|
|
2189
|
+
langId: 0,
|
|
2190
|
+
relationId,
|
|
2191
|
+
action,
|
|
2192
|
+
targetId
|
|
2193
|
+
};
|
|
2194
|
+
this.patch(op);
|
|
2195
|
+
PatchInstance.addPatch(op);
|
|
2196
|
+
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Raw in-memory relation mutation: no patch is emitted. Used by the
|
|
2199
|
+
* generic inverse propagation in patch() and by generated in-side
|
|
2200
|
+
* relation helpers. Idempotent (Set semantics).
|
|
2201
|
+
*/
|
|
2202
|
+
applyRelationRaw(direction, relationId, action, targetId) {
|
|
2203
|
+
const map = direction === "has" ? this._has : this._in;
|
|
2204
|
+
if (!map.has(relationId)) map.set(relationId, /* @__PURE__ */ new Set());
|
|
2205
|
+
if (action === PatchAction.Add) {
|
|
2206
|
+
map.get(relationId).add(targetId);
|
|
2207
|
+
} else {
|
|
2208
|
+
map.get(relationId).delete(targetId);
|
|
2209
|
+
}
|
|
2210
|
+
dbReactivity.trigger(this);
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2213
|
+
* Bulk-restores the inverse (`in`) edges implied by this record's forward
|
|
2214
|
+
* (`has`) relations onto their target records. The sidecar serializes only
|
|
2215
|
+
* the `has` direction (§3.7.1); `mergeExtended` fills `_has`, but the inverse
|
|
2216
|
+
* side (`Person.authorOf`, `Tag.inTags`, …) stays empty until this runs.
|
|
2217
|
+
*
|
|
2218
|
+
* No patch emitted, no reactivity fired (bulk boot path). Idempotent (Set
|
|
2219
|
+
* add). Targets must already be materialized — call after a full
|
|
2220
|
+
* `hydrateAll` pass (see `rebuildInverseRelations`).
|
|
2221
|
+
*/
|
|
2222
|
+
restoreInverses() {
|
|
2223
|
+
for (const [relationId, targets] of this._has) {
|
|
2224
|
+
const rel = this.schema.relations?.find((r) => r.relationId === relationId);
|
|
2225
|
+
if (!rel?.inverted) continue;
|
|
2226
|
+
const targetSchema = Registry.getByName(rel.targetType);
|
|
2227
|
+
const invRel = targetSchema?.relations.find((r) => r.name === rel.inverted);
|
|
2228
|
+
if (!targetSchema || !invRel) continue;
|
|
2229
|
+
for (const targetId of targets) {
|
|
2230
|
+
if (!hasRecord(targetSchema.objectId, targetId, this.creatorUsername)) continue;
|
|
2231
|
+
const target = getRecord(targetSchema.objectId, targetId, this.creatorUsername);
|
|
2232
|
+
let set = target._in.get(invRel.relationId);
|
|
2233
|
+
if (!set) {
|
|
2234
|
+
set = /* @__PURE__ */ new Set();
|
|
2235
|
+
target._in.set(invRel.relationId, set);
|
|
2236
|
+
}
|
|
2237
|
+
set.add(this._id);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
/**
|
|
2242
|
+
* Applies a V2 patch to the in-memory state. Triggers reactivity.
|
|
2243
|
+
*/
|
|
2244
|
+
patch(patch, _isMine = true) {
|
|
2245
|
+
track(patch);
|
|
2246
|
+
switch (patch.operation) {
|
|
2247
|
+
case PatchOperation.EditPropertyString: {
|
|
2248
|
+
const p = patch;
|
|
2249
|
+
if (!this._stringValues.has(p.propertyId)) {
|
|
2250
|
+
this._stringValues.set(p.propertyId, /* @__PURE__ */ new Map());
|
|
2251
|
+
}
|
|
2252
|
+
this._stringValues.get(p.propertyId).set(this.langOf(p.langId), p.value);
|
|
2253
|
+
break;
|
|
2254
|
+
}
|
|
2255
|
+
case PatchOperation.EditPropertyNumber: {
|
|
2256
|
+
const p = patch;
|
|
2257
|
+
if (p.propertyId === LIFECYCLE_STATUS_PROP) {
|
|
2258
|
+
const statusStr = p.value === 1 /* Submitted */ ? "submitted" : p.value === 2 /* CommunityPending */ ? "community_pending" : p.value === 3 /* Canonical */ ? "canonical" : "active";
|
|
2259
|
+
localRecordTable.setStatus(this.creatorUsername, this.id, statusStr).catch((err) => {
|
|
2260
|
+
if (!err.message?.includes("not found")) {
|
|
2261
|
+
console.error("[Orm] Failed to update LocalRecordTable status:", err);
|
|
2262
|
+
}
|
|
2263
|
+
});
|
|
2264
|
+
if (p.value === 3 /* Canonical */) {
|
|
2265
|
+
unpinRecord(this.objectType, this.id, this.creatorUsername);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
const lang = this.langOf(p.langId);
|
|
2269
|
+
if (this.getPropType(p.propertyId) === "boolean") {
|
|
2270
|
+
if (!this._boolValues.has(p.propertyId)) {
|
|
2271
|
+
this._boolValues.set(p.propertyId, /* @__PURE__ */ new Map());
|
|
2272
|
+
}
|
|
2273
|
+
this._boolValues.get(p.propertyId).set(lang, !!p.value);
|
|
2274
|
+
} else {
|
|
2275
|
+
if (!this._numberValues.has(p.propertyId)) {
|
|
2276
|
+
this._numberValues.set(p.propertyId, /* @__PURE__ */ new Map());
|
|
2277
|
+
}
|
|
2278
|
+
this._numberValues.get(p.propertyId).set(lang, p.value);
|
|
2279
|
+
}
|
|
2280
|
+
break;
|
|
2281
|
+
}
|
|
2282
|
+
case PatchOperation.EditInstanceFieldString:
|
|
2283
|
+
case PatchOperation.EditInstanceFieldNumber: {
|
|
2284
|
+
const p = patch;
|
|
2285
|
+
this.applyInstancePatch(p);
|
|
2286
|
+
break;
|
|
2287
|
+
}
|
|
2288
|
+
case PatchOperation.EditRelation: {
|
|
2289
|
+
const p = patch;
|
|
2290
|
+
const rel = this.schema.relations?.find((r) => r.relationId === p.relationId);
|
|
2291
|
+
const direction = rel?.direction ?? (this._in.has(p.relationId) && !this._has.has(p.relationId) ? "in" : "has");
|
|
2292
|
+
this.applyRelationRaw(direction, p.relationId, p.action, p.targetId);
|
|
2293
|
+
if (rel?.inverted) {
|
|
2294
|
+
const targetSchema = Registry.getByName(rel.targetType);
|
|
2295
|
+
const invRel = targetSchema?.relations.find((r) => r.name === rel.inverted);
|
|
2296
|
+
if (targetSchema && invRel && hasRecord(targetSchema.objectId, p.targetId, this.creatorUsername)) {
|
|
2297
|
+
const target = getRecord(targetSchema.objectId, p.targetId, this.creatorUsername);
|
|
2298
|
+
target.applyRelationRaw(invRel.direction, invRel.relationId, p.action, this._id);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
break;
|
|
2302
|
+
}
|
|
2303
|
+
case PatchOperation.SetAlias:
|
|
2304
|
+
break;
|
|
2305
|
+
case PatchOperation.AddInstance: {
|
|
2306
|
+
const p = patch;
|
|
2307
|
+
const lang = this.langOf(p.langId);
|
|
2308
|
+
let arr = this._instances.get(lang);
|
|
2309
|
+
if (!arr) {
|
|
2310
|
+
arr = [];
|
|
2311
|
+
this._instances.set(lang, arr);
|
|
2312
|
+
}
|
|
2313
|
+
while (arr.length <= p.instanceIndex) arr.push({});
|
|
2314
|
+
break;
|
|
2315
|
+
}
|
|
2316
|
+
case PatchOperation.CreateRecord:
|
|
2317
|
+
break;
|
|
2318
|
+
default:
|
|
2319
|
+
throw new Error(`unhandled patch operation ${patch.operation}`);
|
|
2320
|
+
}
|
|
2321
|
+
dbReactivity.trigger(this);
|
|
2322
|
+
}
|
|
2323
|
+
applyInstancePatch(p) {
|
|
2324
|
+
const lang = this.langOf(p.langId);
|
|
2325
|
+
let arr = this._instances.get(lang);
|
|
2326
|
+
if (!arr) {
|
|
2327
|
+
arr = [];
|
|
2328
|
+
this._instances.set(lang, arr);
|
|
2329
|
+
}
|
|
2330
|
+
while (arr.length <= p.instanceIndex) arr.push({});
|
|
2331
|
+
const field = this.schema.instanceFields?.find((f) => f.propId === p.propertyId);
|
|
2332
|
+
const name = field?.name ?? `field${p.propertyId}`;
|
|
2333
|
+
let value = p.value;
|
|
2334
|
+
if (field?.type === "boolean" && typeof value === "number") {
|
|
2335
|
+
value = !!value;
|
|
2336
|
+
}
|
|
2337
|
+
arr[p.instanceIndex][name] = value;
|
|
2338
|
+
}
|
|
2339
|
+
// ─── Typed property access ───────────────────────────────────────────────
|
|
2340
|
+
getPropType(propId) {
|
|
2341
|
+
switch (propId) {
|
|
2342
|
+
case TITLE_PROP:
|
|
2343
|
+
case DESCRIPTION_PROP:
|
|
2344
|
+
case ORIGINAL_LANG_PROP:
|
|
2345
|
+
case PREVIEW_TX_ID_PROP:
|
|
2346
|
+
return "string";
|
|
2347
|
+
case AGE_GRADE_BAND_PROP:
|
|
2348
|
+
case LIFECYCLE_STATUS_PROP:
|
|
2349
|
+
return "number";
|
|
2350
|
+
case SAFE_PROP:
|
|
2351
|
+
case DELETED_PROP:
|
|
2352
|
+
return "boolean";
|
|
2353
|
+
}
|
|
2354
|
+
const propDefinition = this.schema.props.find((prop) => prop.propId === propId);
|
|
2355
|
+
if (typeof propDefinition === "undefined") {
|
|
2356
|
+
throw new Error(`unknown prop ${propId} in schema ${this.schema.name}`);
|
|
2357
|
+
}
|
|
2358
|
+
return propDefinition.type === "enum" ? "number" : propDefinition.type;
|
|
2359
|
+
}
|
|
2360
|
+
getProp(propId, lang) {
|
|
2361
|
+
dbReactivity.track(this);
|
|
2362
|
+
const l = lang ?? Config.userLang;
|
|
2363
|
+
switch (this.getPropType(propId)) {
|
|
2364
|
+
case "string":
|
|
2365
|
+
return resolveLangValue(this._stringValues.get(propId), l) ?? "";
|
|
2366
|
+
case "number":
|
|
2367
|
+
return resolveLangValue(this._numberValues.get(propId), l);
|
|
2368
|
+
case "boolean":
|
|
2369
|
+
return resolveLangValue(this._boolValues.get(propId), l);
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
/** Direct state write — no patch emitted (used by merge methods). */
|
|
2373
|
+
setRaw(propId, value, lang = LANG_AGNOSTIC) {
|
|
2374
|
+
switch (this.getPropType(propId)) {
|
|
2375
|
+
case "string": {
|
|
2376
|
+
if (!this._stringValues.has(propId)) this._stringValues.set(propId, /* @__PURE__ */ new Map());
|
|
2377
|
+
this._stringValues.get(propId).set(lang, value);
|
|
2378
|
+
break;
|
|
2379
|
+
}
|
|
2380
|
+
case "number": {
|
|
2381
|
+
if (!this._numberValues.has(propId)) this._numberValues.set(propId, /* @__PURE__ */ new Map());
|
|
2382
|
+
this._numberValues.get(propId).set(lang, value);
|
|
2383
|
+
break;
|
|
2384
|
+
}
|
|
2385
|
+
case "boolean": {
|
|
2386
|
+
if (!this._boolValues.has(propId)) this._boolValues.set(propId, /* @__PURE__ */ new Map());
|
|
2387
|
+
this._boolValues.get(propId).set(lang, !!value);
|
|
2388
|
+
break;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
// ─── Instances ───────────────────────────────────────────────────────────
|
|
2393
|
+
getInstancesData(lang) {
|
|
2394
|
+
dbReactivity.track(this);
|
|
2395
|
+
return this._instances.get(lang ?? Config.userLang) ?? [];
|
|
2396
|
+
}
|
|
2397
|
+
getDefaultInstanceData(lang) {
|
|
2398
|
+
const all = this.getInstancesData(lang);
|
|
2399
|
+
return all.find((i) => i["isDefault"] === true) ?? all[0];
|
|
2400
|
+
}
|
|
2401
|
+
/** Direct state write — no patch emitted (used by mergeExtended/mergeSlim). */
|
|
2402
|
+
setInstancesRaw(lang, instances) {
|
|
2403
|
+
this._instances.set(lang, instances);
|
|
2404
|
+
}
|
|
2405
|
+
growInstances(lang, toIndex) {
|
|
2406
|
+
let arr = this._instances.get(lang);
|
|
2407
|
+
if (!arr) {
|
|
2408
|
+
arr = [];
|
|
2409
|
+
this._instances.set(lang, arr);
|
|
2410
|
+
}
|
|
2411
|
+
while (arr.length <= toIndex) {
|
|
2412
|
+
arr.push({});
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
addInstance(lang) {
|
|
2416
|
+
if (!this.schema.multipleInstances) {
|
|
2417
|
+
throw new Error(`Model ${this.constructor.name} does not support multiple instances.`);
|
|
2418
|
+
}
|
|
2419
|
+
const targetLang = lang ?? Config.userLang;
|
|
2420
|
+
const instances = this.getInstancesData(targetLang);
|
|
2421
|
+
const index = instances.length;
|
|
2422
|
+
this.growInstances(targetLang, index);
|
|
2423
|
+
const op = {
|
|
2424
|
+
operation: PatchOperation.AddInstance,
|
|
2425
|
+
objectType: this.objectType,
|
|
2426
|
+
objectId: this.id,
|
|
2427
|
+
langId: this.langIdOf(targetLang),
|
|
2428
|
+
instanceIndex: index
|
|
2429
|
+
};
|
|
2430
|
+
this.patch(op);
|
|
2431
|
+
PatchInstance.addPatch(op);
|
|
2432
|
+
return index;
|
|
2433
|
+
}
|
|
2434
|
+
// ─── Provenance ──────────────────────────────────────────────────────────
|
|
2435
|
+
getProvenance(propId, lang) {
|
|
2436
|
+
dbReactivity.track(this);
|
|
2437
|
+
return this._provenance.get(lang ?? Config.userLang)?.get(propId) ?? 0;
|
|
2438
|
+
}
|
|
2439
|
+
setProvenanceRaw(lang, propId, value) {
|
|
2440
|
+
if (!this._provenance.has(lang)) this._provenance.set(lang, /* @__PURE__ */ new Map());
|
|
2441
|
+
this._provenance.get(lang).set(propId, value);
|
|
2442
|
+
}
|
|
2443
|
+
// ─── Generic Merge ───────────────────────────────────────────────────────
|
|
2444
|
+
mergeSlim(cols, index, lang = Config.userLang) {
|
|
2445
|
+
this.setRaw(0, cols.titles?.[index] ?? "", lang);
|
|
2446
|
+
this.setRaw(2, cols.originalLangs?.[index] ?? "", lang);
|
|
2447
|
+
this.setRaw(4, cols.previewTxIds?.[index] ?? "", lang);
|
|
2448
|
+
this.setRaw(3, cols.ageGradeBands?.[index], lang);
|
|
2449
|
+
this.setRaw(5, cols.safes?.[index] === 1, lang);
|
|
2450
|
+
this.setRaw(6, cols.deleteds?.[index] === 1, lang);
|
|
2451
|
+
for (const prop of this.schema.props) {
|
|
2452
|
+
if (prop.source !== "slim") continue;
|
|
2453
|
+
const name = colName(prop.name, prop.type);
|
|
2454
|
+
const val = cols[name]?.[index];
|
|
2455
|
+
if (prop.type === "string") {
|
|
2456
|
+
this.setRaw(prop.propId, val ?? "", lang);
|
|
2457
|
+
} else if (prop.type === "boolean") {
|
|
2458
|
+
this.setRaw(prop.propId, val === 1, lang);
|
|
2459
|
+
} else {
|
|
2460
|
+
this.setRaw(prop.propId, val, lang);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
if (this.schema.multipleInstances) {
|
|
2464
|
+
const firstStrField = this.schema.instanceFields?.find((f) => f.type === "string");
|
|
2465
|
+
let hasDefault = true;
|
|
2466
|
+
if (firstStrField) {
|
|
2467
|
+
const name = `default${colName(capitalize(firstStrField.name), firstStrField.type)}`;
|
|
2468
|
+
if (cols[name]?.[index] == null) {
|
|
2469
|
+
hasDefault = false;
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
if (hasDefault && this.getInstancesData(lang).length === 0) {
|
|
2473
|
+
const inst = { isDefault: true };
|
|
2474
|
+
for (const field of this.schema.instanceFields || []) {
|
|
2475
|
+
const name = `default${colName(capitalize(field.name), field.type)}`;
|
|
2476
|
+
const val = cols[name]?.[index];
|
|
2477
|
+
if (field.type === "boolean") {
|
|
2478
|
+
inst[field.name] = val === 1;
|
|
2479
|
+
} else {
|
|
2480
|
+
inst[field.name] = val ?? null;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
this.setInstancesRaw(lang, [inst]);
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
mergeExtended(cols, index, lang = Config.userLang) {
|
|
2488
|
+
this.setRaw(1, cols.descriptions?.[index] ?? "", lang);
|
|
2489
|
+
for (const prop of this.schema.props) {
|
|
2490
|
+
if (prop.source !== "extended") continue;
|
|
2491
|
+
const name = colName(prop.name, prop.type);
|
|
2492
|
+
const val = cols[name]?.[index];
|
|
2493
|
+
if (prop.type === "string") {
|
|
2494
|
+
this.setRaw(prop.propId, val ?? "", lang);
|
|
2495
|
+
} else if (prop.type === "boolean") {
|
|
2496
|
+
this.setRaw(prop.propId, val === 1, lang);
|
|
2497
|
+
} else {
|
|
2498
|
+
this.setRaw(prop.propId, val, lang);
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
for (const rel of this.schema.relations || []) {
|
|
2502
|
+
if (rel.direction !== "has") continue;
|
|
2503
|
+
const field = relationColName2(rel);
|
|
2504
|
+
if (cols[field]) {
|
|
2505
|
+
const set = this._has.get(rel.relationId);
|
|
2506
|
+
for (const targetId of cols[field][index] ?? []) {
|
|
2507
|
+
set.add(targetId);
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
if (this.schema.multipleInstances) {
|
|
2512
|
+
if (cols.instances) {
|
|
2513
|
+
this.setInstancesRaw(lang, cols.instances[index] ?? []);
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
mergeProv(cols, index, lang = Config.userLang) {
|
|
2518
|
+
const BASE_PROP_IDS = {
|
|
2519
|
+
title: 0,
|
|
2520
|
+
description: 1,
|
|
2521
|
+
originalLang: 2,
|
|
2522
|
+
ageGradeBand: 3,
|
|
2523
|
+
previewTxId: 4,
|
|
2524
|
+
safe: 5,
|
|
2525
|
+
deleted: 6,
|
|
2526
|
+
lifecycleStatus: 7
|
|
2527
|
+
};
|
|
2528
|
+
for (const [name, arr] of Object.entries(cols.fields || {})) {
|
|
2529
|
+
let propId = BASE_PROP_IDS[name];
|
|
2530
|
+
if (propId === void 0) {
|
|
2531
|
+
const prop = this.schema.props.find((p) => p.name === name);
|
|
2532
|
+
if (prop) {
|
|
2533
|
+
propId = prop.propId;
|
|
2534
|
+
} else if (this.schema.instanceFields) {
|
|
2535
|
+
const field = this.schema.instanceFields.find((f) => f.name === name);
|
|
2536
|
+
if (field) propId = field.propId;
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
if (propId !== void 0) {
|
|
2540
|
+
this.setProvenanceRaw(lang, propId, arr[index]);
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
};
|
|
2545
|
+
|
|
2546
|
+
// src/models/pid.ts
|
|
2547
|
+
var BASE34_ALPHABET = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
2548
|
+
var ISO_ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
|
|
2549
|
+
function computeMod37_2(input) {
|
|
2550
|
+
let p = 0;
|
|
2551
|
+
for (let i = 0; i < input.length; i++) {
|
|
2552
|
+
const val = ISO_ALPHABET.indexOf(input[i]);
|
|
2553
|
+
if (val === -1) {
|
|
2554
|
+
throw new Error(`[pid] Invalid character for ISO 7064 MOD 37-2: ${input[i]}`);
|
|
2555
|
+
}
|
|
2556
|
+
let s = (p + val) % 37;
|
|
2557
|
+
if (s === 0) s = 37;
|
|
2558
|
+
p = s * 2 % 37;
|
|
2559
|
+
}
|
|
2560
|
+
const checkVal = (38 - p) % 37;
|
|
2561
|
+
let checkChar = ISO_ALPHABET[checkVal];
|
|
2562
|
+
if (checkChar === "*") checkChar = "X";
|
|
2563
|
+
if (checkChar === "I") checkChar = "J";
|
|
2564
|
+
if (checkChar === "O") checkChar = "P";
|
|
2565
|
+
return checkChar;
|
|
2566
|
+
}
|
|
2567
|
+
function base34(wireId) {
|
|
2568
|
+
if (!Number.isInteger(wireId) || wireId < 0 || wireId > 4294967295) {
|
|
2569
|
+
throw new Error(`[pid] wireId ${wireId} must be an unsigned 32-bit integer`);
|
|
2570
|
+
}
|
|
2571
|
+
if (wireId === 0) return "0000000";
|
|
2572
|
+
let str = "";
|
|
2573
|
+
let val = wireId;
|
|
2574
|
+
while (val > 0) {
|
|
2575
|
+
str = BASE34_ALPHABET[val % 34] + str;
|
|
2576
|
+
val = Math.floor(val / 34);
|
|
2577
|
+
}
|
|
2578
|
+
return str.padStart(7, "0");
|
|
2579
|
+
}
|
|
2580
|
+
function unbase34(str) {
|
|
2581
|
+
if (str.length !== 7) {
|
|
2582
|
+
throw new Error(`[pid] Base34 body must be exactly 7 characters, got ${str.length}`);
|
|
2583
|
+
}
|
|
2584
|
+
let val = 0;
|
|
2585
|
+
for (let i = 0; i < str.length; i++) {
|
|
2586
|
+
const idx = BASE34_ALPHABET.indexOf(str[i]);
|
|
2587
|
+
if (idx === -1) {
|
|
2588
|
+
throw new Error(`[pid] Invalid character in base-34 body: ${str[i]}`);
|
|
2589
|
+
}
|
|
2590
|
+
val = val * 34 + idx;
|
|
2591
|
+
}
|
|
2592
|
+
return val;
|
|
2593
|
+
}
|
|
2594
|
+
function encodePID(typePrefix, wireId) {
|
|
2595
|
+
if (typePrefix.length !== 2) {
|
|
2596
|
+
throw new Error(`[pid] typePrefix must be exactly 2 characters`);
|
|
2597
|
+
}
|
|
2598
|
+
const body = base34(wireId);
|
|
2599
|
+
const check2 = computeMod37_2(typePrefix + body);
|
|
2600
|
+
return typePrefix + body + check2;
|
|
2601
|
+
}
|
|
2602
|
+
function decodePID(typePrefix, pid) {
|
|
2603
|
+
if (!pid.startsWith(typePrefix)) {
|
|
2604
|
+
throw new Error(`[pid] PID ${pid} does not start with expected prefix ${typePrefix}`);
|
|
2605
|
+
}
|
|
2606
|
+
if (pid.length !== 10) {
|
|
2607
|
+
throw new Error(`[pid] PID must be exactly 10 characters long, got ${pid.length}`);
|
|
2608
|
+
}
|
|
2609
|
+
const body = pid.slice(2, 9);
|
|
2610
|
+
const providedCheck = pid[9];
|
|
2611
|
+
const expectedCheck = computeMod37_2(typePrefix + body);
|
|
2612
|
+
if (providedCheck !== expectedCheck) {
|
|
2613
|
+
throw new Error(`[pid] Invalid check character in PID ${pid}. Expected ${expectedCheck}`);
|
|
2614
|
+
}
|
|
2615
|
+
return { wireId: unbase34(body) };
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
// ../db_schemas/dist/schemas.js
|
|
2619
|
+
var schemas = {
|
|
2620
|
+
"Book": {
|
|
2621
|
+
"name": "Book",
|
|
2622
|
+
"typePrefix": "BK",
|
|
2623
|
+
"canonical": true,
|
|
2624
|
+
"uidStrategy": "native-only",
|
|
2625
|
+
"multipleInstances": true,
|
|
2626
|
+
"instanceUidStrategy": [
|
|
2627
|
+
"isbn"
|
|
2628
|
+
],
|
|
2629
|
+
"props": [
|
|
2630
|
+
{
|
|
2631
|
+
"name": "prerequisites",
|
|
2632
|
+
"type": "string",
|
|
2633
|
+
"source": "extended",
|
|
2634
|
+
"propId": 8
|
|
2635
|
+
},
|
|
2636
|
+
{
|
|
2637
|
+
"name": "deweyDecimal",
|
|
2638
|
+
"type": "string",
|
|
2639
|
+
"source": "extended",
|
|
2640
|
+
"propId": 9
|
|
2641
|
+
},
|
|
2642
|
+
{
|
|
2643
|
+
"name": "locCallNumber",
|
|
2644
|
+
"type": "string",
|
|
2645
|
+
"source": "extended",
|
|
2646
|
+
"propId": 10
|
|
2647
|
+
},
|
|
2648
|
+
{
|
|
2649
|
+
"name": "copyrightStatus",
|
|
2650
|
+
"type": "enum",
|
|
2651
|
+
"enum": "CopyrightStatus",
|
|
2652
|
+
"source": "extended",
|
|
2653
|
+
"propId": 11
|
|
2654
|
+
},
|
|
2655
|
+
{
|
|
2656
|
+
"name": "textQuality",
|
|
2657
|
+
"type": "enum",
|
|
2658
|
+
"enum": "QualityScore",
|
|
2659
|
+
"source": "extended",
|
|
2660
|
+
"propId": 12
|
|
2661
|
+
},
|
|
2662
|
+
{
|
|
2663
|
+
"name": "illustrations",
|
|
2664
|
+
"type": "enum",
|
|
2665
|
+
"enum": "QualityScore",
|
|
2666
|
+
"source": "extended",
|
|
2667
|
+
"propId": 13
|
|
2668
|
+
},
|
|
2669
|
+
{
|
|
2670
|
+
"name": "educationQuality",
|
|
2671
|
+
"type": "enum",
|
|
2672
|
+
"enum": "QualityScore",
|
|
2673
|
+
"source": "extended",
|
|
2674
|
+
"propId": 14
|
|
2675
|
+
},
|
|
2676
|
+
{
|
|
2677
|
+
"name": "practicality",
|
|
2678
|
+
"type": "enum",
|
|
2679
|
+
"enum": "QualityScore",
|
|
2680
|
+
"source": "extended",
|
|
2681
|
+
"propId": 15
|
|
2682
|
+
},
|
|
2683
|
+
{
|
|
2684
|
+
"name": "accessibilityLevel",
|
|
2685
|
+
"type": "enum",
|
|
2686
|
+
"enum": "QualityScore",
|
|
2687
|
+
"source": "extended",
|
|
2688
|
+
"propId": 16
|
|
2689
|
+
},
|
|
2690
|
+
{
|
|
2691
|
+
"name": "teacherMaterials",
|
|
2692
|
+
"type": "boolean",
|
|
2693
|
+
"source": "extended",
|
|
2694
|
+
"propId": 17
|
|
2695
|
+
},
|
|
2696
|
+
{
|
|
2697
|
+
"name": "pedagogicalScaffolding",
|
|
2698
|
+
"type": "enum",
|
|
2699
|
+
"enum": "QualityScore",
|
|
2700
|
+
"source": "extended",
|
|
2701
|
+
"propId": 18
|
|
2702
|
+
},
|
|
2703
|
+
{
|
|
2704
|
+
"name": "clarityOfExplanation",
|
|
2705
|
+
"type": "enum",
|
|
2706
|
+
"enum": "QualityScore",
|
|
2707
|
+
"source": "extended",
|
|
2708
|
+
"propId": 19
|
|
2709
|
+
},
|
|
2710
|
+
{
|
|
2711
|
+
"name": "workedExamples",
|
|
2712
|
+
"type": "enum",
|
|
2713
|
+
"enum": "QualityScore",
|
|
2714
|
+
"source": "extended",
|
|
2715
|
+
"propId": 20
|
|
2716
|
+
},
|
|
2717
|
+
{
|
|
2718
|
+
"name": "exercisesAndAssessment",
|
|
2719
|
+
"type": "enum",
|
|
2720
|
+
"enum": "QualityScore",
|
|
2721
|
+
"source": "extended",
|
|
2722
|
+
"propId": 21
|
|
2723
|
+
},
|
|
2724
|
+
{
|
|
2725
|
+
"name": "selfStudyReadiness",
|
|
2726
|
+
"type": "enum",
|
|
2727
|
+
"enum": "QualityScore",
|
|
2728
|
+
"source": "extended",
|
|
2729
|
+
"propId": 22
|
|
2730
|
+
},
|
|
2731
|
+
{
|
|
2732
|
+
"name": "referenceApparatus",
|
|
2733
|
+
"type": "enum",
|
|
2734
|
+
"enum": "QualityScore",
|
|
2735
|
+
"source": "extended",
|
|
2736
|
+
"propId": 23
|
|
2737
|
+
},
|
|
2738
|
+
{
|
|
2739
|
+
"name": "safetyGuidance",
|
|
2740
|
+
"type": "enum",
|
|
2741
|
+
"enum": "QualityScore",
|
|
2742
|
+
"source": "extended",
|
|
2743
|
+
"propId": 24
|
|
2744
|
+
},
|
|
2745
|
+
{
|
|
2746
|
+
"name": "contentCurrency",
|
|
2747
|
+
"type": "enum",
|
|
2748
|
+
"enum": "QualityScore",
|
|
2749
|
+
"source": "extended",
|
|
2750
|
+
"propId": 25
|
|
2751
|
+
},
|
|
2752
|
+
{
|
|
2753
|
+
"name": "ecoRegeneration",
|
|
2754
|
+
"type": "enum",
|
|
2755
|
+
"enum": "QualityScore",
|
|
2756
|
+
"source": "extended",
|
|
2757
|
+
"propId": 26
|
|
2758
|
+
},
|
|
2759
|
+
{
|
|
2760
|
+
"name": "communityLiving",
|
|
2761
|
+
"type": "enum",
|
|
2762
|
+
"enum": "QualityScore",
|
|
2763
|
+
"source": "extended",
|
|
2764
|
+
"propId": 27
|
|
2765
|
+
},
|
|
2766
|
+
{
|
|
2767
|
+
"name": "promotesPeace",
|
|
2768
|
+
"type": "enum",
|
|
2769
|
+
"enum": "QualityScore",
|
|
2770
|
+
"source": "extended",
|
|
2771
|
+
"propId": 28
|
|
2772
|
+
},
|
|
2773
|
+
{
|
|
2774
|
+
"name": "businessDevelopment",
|
|
2775
|
+
"type": "enum",
|
|
2776
|
+
"enum": "QualityScore",
|
|
2777
|
+
"source": "extended",
|
|
2778
|
+
"propId": 29
|
|
2779
|
+
}
|
|
2780
|
+
],
|
|
2781
|
+
"instanceFields": [
|
|
2782
|
+
{
|
|
2783
|
+
"name": "language",
|
|
2784
|
+
"type": "string",
|
|
2785
|
+
"identityComponent": true,
|
|
2786
|
+
"propId": 30
|
|
2787
|
+
},
|
|
2788
|
+
{
|
|
2789
|
+
"name": "downloadTxId",
|
|
2790
|
+
"type": "string",
|
|
2791
|
+
"propId": 31
|
|
2792
|
+
},
|
|
2793
|
+
{
|
|
2794
|
+
"name": "method",
|
|
2795
|
+
"type": "enum",
|
|
2796
|
+
"enum": "BookMethod",
|
|
2797
|
+
"propId": 32
|
|
2798
|
+
},
|
|
2799
|
+
{
|
|
2800
|
+
"name": "isAiTranslation",
|
|
2801
|
+
"type": "boolean",
|
|
2802
|
+
"propId": 33
|
|
2803
|
+
},
|
|
2804
|
+
{
|
|
2805
|
+
"name": "aiEngine",
|
|
2806
|
+
"type": "string",
|
|
2807
|
+
"nullable": true,
|
|
2808
|
+
"propId": 34
|
|
2809
|
+
},
|
|
2810
|
+
{
|
|
2811
|
+
"name": "addedAt",
|
|
2812
|
+
"type": "number",
|
|
2813
|
+
"bits": 32,
|
|
2814
|
+
"propId": 35
|
|
2815
|
+
},
|
|
2816
|
+
{
|
|
2817
|
+
"name": "nbPages",
|
|
2818
|
+
"type": "number",
|
|
2819
|
+
"bits": 16,
|
|
2820
|
+
"propId": 36
|
|
2821
|
+
},
|
|
2822
|
+
{
|
|
2823
|
+
"name": "sizeBytes",
|
|
2824
|
+
"type": "number",
|
|
2825
|
+
"bits": 32,
|
|
2826
|
+
"propId": 37
|
|
2827
|
+
},
|
|
2828
|
+
{
|
|
2829
|
+
"name": "publisher",
|
|
2830
|
+
"type": "string",
|
|
2831
|
+
"nullable": true,
|
|
2832
|
+
"propId": 38
|
|
2833
|
+
},
|
|
2834
|
+
{
|
|
2835
|
+
"name": "publicationDate",
|
|
2836
|
+
"type": "string",
|
|
2837
|
+
"nullable": true,
|
|
2838
|
+
"propId": 39
|
|
2839
|
+
},
|
|
2840
|
+
{
|
|
2841
|
+
"name": "publishedAt",
|
|
2842
|
+
"type": "string",
|
|
2843
|
+
"nullable": true,
|
|
2844
|
+
"propId": 40
|
|
2845
|
+
},
|
|
2846
|
+
{
|
|
2847
|
+
"name": "qualityScore",
|
|
2848
|
+
"type": "enum",
|
|
2849
|
+
"enum": "QualityScore",
|
|
2850
|
+
"propId": 41
|
|
2851
|
+
},
|
|
2852
|
+
{
|
|
2853
|
+
"name": "isbn",
|
|
2854
|
+
"type": "string",
|
|
2855
|
+
"nullable": true,
|
|
2856
|
+
"source": "extended",
|
|
2857
|
+
"propId": 42
|
|
2858
|
+
}
|
|
2859
|
+
],
|
|
2860
|
+
"relations": [
|
|
2861
|
+
{
|
|
2862
|
+
"name": "inTags",
|
|
2863
|
+
"targetType": "Tag",
|
|
2864
|
+
"direction": "in",
|
|
2865
|
+
"inverted": "books",
|
|
2866
|
+
"relationId": 0
|
|
2867
|
+
},
|
|
2868
|
+
{
|
|
2869
|
+
"name": "authors",
|
|
2870
|
+
"targetType": "Person",
|
|
2871
|
+
"direction": "has",
|
|
2872
|
+
"inverted": "authorOf",
|
|
2873
|
+
"relationId": 1
|
|
2874
|
+
}
|
|
2875
|
+
],
|
|
2876
|
+
"translations": {
|
|
2877
|
+
"fr": {
|
|
2878
|
+
"className": "Livre",
|
|
2879
|
+
"props": {
|
|
2880
|
+
"title": "titre",
|
|
2881
|
+
"description": "description"
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
},
|
|
2885
|
+
"standardPks": {
|
|
2886
|
+
"isbn": "isbn"
|
|
2887
|
+
},
|
|
2888
|
+
"objectId": 0
|
|
2889
|
+
},
|
|
2890
|
+
"Person": {
|
|
2891
|
+
"name": "Person",
|
|
2892
|
+
"typePrefix": "PR",
|
|
2893
|
+
"canonical": true,
|
|
2894
|
+
"uidStrategy": [
|
|
2895
|
+
"isni",
|
|
2896
|
+
"orcid"
|
|
2897
|
+
],
|
|
2898
|
+
"multipleInstances": false,
|
|
2899
|
+
"props": [
|
|
2900
|
+
{
|
|
2901
|
+
"name": "birthDate",
|
|
2902
|
+
"type": "string",
|
|
2903
|
+
"source": "extended",
|
|
2904
|
+
"propId": 43
|
|
2905
|
+
},
|
|
2906
|
+
{
|
|
2907
|
+
"name": "deathDate",
|
|
2908
|
+
"type": "string",
|
|
2909
|
+
"source": "extended",
|
|
2910
|
+
"propId": 44
|
|
2911
|
+
},
|
|
2912
|
+
{
|
|
2913
|
+
"name": "nationality",
|
|
2914
|
+
"type": "string",
|
|
2915
|
+
"source": "extended",
|
|
2916
|
+
"propId": 45
|
|
2917
|
+
},
|
|
2918
|
+
{
|
|
2919
|
+
"name": "wikiUrl",
|
|
2920
|
+
"type": "string",
|
|
2921
|
+
"source": "extended",
|
|
2922
|
+
"propId": 46
|
|
2923
|
+
},
|
|
2924
|
+
{
|
|
2925
|
+
"name": "isniId",
|
|
2926
|
+
"type": "string",
|
|
2927
|
+
"nullable": true,
|
|
2928
|
+
"source": "extended",
|
|
2929
|
+
"propId": 47
|
|
2930
|
+
},
|
|
2931
|
+
{
|
|
2932
|
+
"name": "orcidId",
|
|
2933
|
+
"type": "string",
|
|
2934
|
+
"nullable": true,
|
|
2935
|
+
"source": "extended",
|
|
2936
|
+
"propId": 48
|
|
2937
|
+
}
|
|
2938
|
+
],
|
|
2939
|
+
"instanceFields": [],
|
|
2940
|
+
"relations": [
|
|
2941
|
+
{
|
|
2942
|
+
"name": "authorOf",
|
|
2943
|
+
"targetType": "Book",
|
|
2944
|
+
"direction": "in",
|
|
2945
|
+
"inverted": "authors",
|
|
2946
|
+
"relationId": 2
|
|
2947
|
+
}
|
|
2948
|
+
],
|
|
2949
|
+
"translations": {
|
|
2950
|
+
"fr": {
|
|
2951
|
+
"className": "Personne"
|
|
2952
|
+
}
|
|
2953
|
+
},
|
|
2954
|
+
"standardPks": {
|
|
2955
|
+
"isni": "isniId",
|
|
2956
|
+
"orcid": "orcidId"
|
|
2957
|
+
},
|
|
2958
|
+
"objectId": 1
|
|
2959
|
+
},
|
|
2960
|
+
"Tag": {
|
|
2961
|
+
"name": "Tag",
|
|
2962
|
+
"typePrefix": "TG",
|
|
2963
|
+
"canonical": true,
|
|
2964
|
+
"uidStrategy": [
|
|
2965
|
+
"lcc",
|
|
2966
|
+
"ddc",
|
|
2967
|
+
"udc",
|
|
2968
|
+
"clc",
|
|
2969
|
+
"bbk",
|
|
2970
|
+
"tlc",
|
|
2971
|
+
"cc"
|
|
2972
|
+
],
|
|
2973
|
+
"multipleInstances": false,
|
|
2974
|
+
"props": [
|
|
2975
|
+
{
|
|
2976
|
+
"name": "lccNotation",
|
|
2977
|
+
"type": "string",
|
|
2978
|
+
"nullable": true,
|
|
2979
|
+
"source": "extended",
|
|
2980
|
+
"propId": 50
|
|
2981
|
+
},
|
|
2982
|
+
{
|
|
2983
|
+
"name": "ddcNotation",
|
|
2984
|
+
"type": "string",
|
|
2985
|
+
"nullable": true,
|
|
2986
|
+
"source": "extended",
|
|
2987
|
+
"propId": 49
|
|
2988
|
+
},
|
|
2989
|
+
{
|
|
2990
|
+
"name": "udcNotation",
|
|
2991
|
+
"type": "string",
|
|
2992
|
+
"nullable": true,
|
|
2993
|
+
"source": "extended",
|
|
2994
|
+
"propId": 51
|
|
2995
|
+
},
|
|
2996
|
+
{
|
|
2997
|
+
"name": "clcNotation",
|
|
2998
|
+
"type": "string",
|
|
2999
|
+
"nullable": true,
|
|
3000
|
+
"source": "extended",
|
|
3001
|
+
"propId": 52
|
|
3002
|
+
},
|
|
3003
|
+
{
|
|
3004
|
+
"name": "bbkNotation",
|
|
3005
|
+
"type": "string",
|
|
3006
|
+
"nullable": true,
|
|
3007
|
+
"source": "extended",
|
|
3008
|
+
"propId": 53
|
|
3009
|
+
},
|
|
3010
|
+
{
|
|
3011
|
+
"name": "tlcNotation",
|
|
3012
|
+
"type": "string",
|
|
3013
|
+
"nullable": true,
|
|
3014
|
+
"source": "extended",
|
|
3015
|
+
"propId": 54
|
|
3016
|
+
},
|
|
3017
|
+
{
|
|
3018
|
+
"name": "ccNotation",
|
|
3019
|
+
"type": "string",
|
|
3020
|
+
"nullable": true,
|
|
3021
|
+
"source": "extended",
|
|
3022
|
+
"propId": 55
|
|
3023
|
+
}
|
|
3024
|
+
],
|
|
3025
|
+
"instanceFields": [],
|
|
3026
|
+
"relations": [
|
|
3027
|
+
{
|
|
3028
|
+
"name": "inTags",
|
|
3029
|
+
"targetType": "Tag",
|
|
3030
|
+
"direction": "in",
|
|
3031
|
+
"inverted": "tags",
|
|
3032
|
+
"relationId": 0
|
|
3033
|
+
},
|
|
3034
|
+
{
|
|
3035
|
+
"name": "tags",
|
|
3036
|
+
"targetType": "Tag",
|
|
3037
|
+
"direction": "has",
|
|
3038
|
+
"inverted": "inTags",
|
|
3039
|
+
"relationId": 3
|
|
3040
|
+
},
|
|
3041
|
+
{
|
|
3042
|
+
"name": "books",
|
|
3043
|
+
"targetType": "Book",
|
|
3044
|
+
"direction": "has",
|
|
3045
|
+
"inverted": "inTags",
|
|
3046
|
+
"relationId": 4
|
|
3047
|
+
}
|
|
3048
|
+
],
|
|
3049
|
+
"standardPks": {
|
|
3050
|
+
"lcc": "lccNotation",
|
|
3051
|
+
"ddc": "ddcNotation",
|
|
3052
|
+
"udc": "udcNotation",
|
|
3053
|
+
"clc": "clcNotation",
|
|
3054
|
+
"bbk": "bbkNotation",
|
|
3055
|
+
"tlc": "tlcNotation",
|
|
3056
|
+
"cc": "ccNotation"
|
|
3057
|
+
},
|
|
3058
|
+
"objectId": 2
|
|
3059
|
+
}
|
|
3060
|
+
};
|
|
3061
|
+
|
|
3062
|
+
// ../standard-adapters/dist/chunk-DX6SH342.js
|
|
3063
|
+
function validateISNIMod11_2(compact) {
|
|
3064
|
+
if (compact.length !== 16) return { valid: false, error: `Expected 16 chars, got ${compact.length}` };
|
|
3065
|
+
let p = 0;
|
|
3066
|
+
for (let i = 0; i < 15; i++) {
|
|
3067
|
+
const d = parseInt(compact[i], 10);
|
|
3068
|
+
if (isNaN(d)) return { valid: false, error: `Non-digit character at position ${i}` };
|
|
3069
|
+
p = (p + d) * 2 % 11;
|
|
3070
|
+
}
|
|
3071
|
+
const checkVal = (12 - p) % 11;
|
|
3072
|
+
const checkChar = checkVal === 10 ? "X" : String(checkVal);
|
|
3073
|
+
if (compact[15].toUpperCase() !== checkChar)
|
|
3074
|
+
return { valid: false, error: `Check digit mismatch: expected ${checkChar}, got ${compact[15]}` };
|
|
3075
|
+
return { valid: true };
|
|
3076
|
+
}
|
|
3077
|
+
var ISNIAdapter = {
|
|
3078
|
+
standardId: "isni",
|
|
3079
|
+
uriScheme: "ISNI",
|
|
3080
|
+
normalize(value) {
|
|
3081
|
+
return value.replace(/[\s-]/g, "");
|
|
3082
|
+
},
|
|
3083
|
+
display(value) {
|
|
3084
|
+
const compact = ISNIAdapter.normalize(value);
|
|
3085
|
+
if (compact.length === 16)
|
|
3086
|
+
return `${compact.slice(0, 4)} ${compact.slice(4, 8)} ${compact.slice(8, 12)} ${compact.slice(12)}`;
|
|
3087
|
+
return compact;
|
|
3088
|
+
},
|
|
3089
|
+
validate(value) {
|
|
3090
|
+
if (!value) return { valid: false, error: "ISNI is absent" };
|
|
3091
|
+
const compact = ISNIAdapter.normalize(value);
|
|
3092
|
+
if (!/^[0-9]{15}[0-9X]$/.test(compact))
|
|
3093
|
+
return { valid: false, error: `ISNI does not match pattern: ${compact}` };
|
|
3094
|
+
return validateISNIMod11_2(compact);
|
|
3095
|
+
},
|
|
3096
|
+
toLinkedDataUri(value) {
|
|
3097
|
+
return `https://isni.org/isni/${ISNIAdapter.normalize(value)}`;
|
|
3098
|
+
},
|
|
3099
|
+
apis: {
|
|
3100
|
+
"isni-sru": {
|
|
3101
|
+
apiId: "isni-sru",
|
|
3102
|
+
name: "ISNI SRU API",
|
|
3103
|
+
async fetch({ isniId }) {
|
|
3104
|
+
if (!isniId) return [];
|
|
3105
|
+
const query = `pica.isn%3D${encodeURIComponent(isniId)}`;
|
|
3106
|
+
const url = `https://isni.oclc.org/sru/DB=1.2/?operation=searchRetrieve&query=${query}&recordSchema=isni-b&maximumRecords=10`;
|
|
3107
|
+
const res = await fetch(url, { headers: { Accept: "application/xml" } });
|
|
3108
|
+
if (!res.ok) return [];
|
|
3109
|
+
const text = await res.text();
|
|
3110
|
+
const isniMatch = text.match(/<isniUnformatted>([0-9X]+)<\/isniUnformatted>/);
|
|
3111
|
+
const forenameMatch = text.match(/<forename>([^<]+)<\/forename>/);
|
|
3112
|
+
const surnameMatch = text.match(/<surname>([^<]+)<\/surname>/);
|
|
3113
|
+
if (!isniMatch) return [];
|
|
3114
|
+
return [{
|
|
3115
|
+
isni: isniMatch[1],
|
|
3116
|
+
forename: forenameMatch?.[1],
|
|
3117
|
+
surname: surnameMatch?.[1]
|
|
3118
|
+
}];
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
3122
|
+
};
|
|
3123
|
+
|
|
3124
|
+
// ../standard-adapters/dist/chunk-KNGZ7NJF.js
|
|
3125
|
+
function validateORCIDMod11_2(compact) {
|
|
3126
|
+
if (compact.length !== 16) return { valid: false, error: `Expected 16 chars, got ${compact.length}` };
|
|
3127
|
+
let p = 0;
|
|
3128
|
+
for (let i = 0; i < 15; i++) {
|
|
3129
|
+
const d = parseInt(compact[i], 10);
|
|
3130
|
+
if (isNaN(d)) return { valid: false, error: `Non-digit at position ${i}` };
|
|
3131
|
+
p = (p + d) * 2 % 11;
|
|
3132
|
+
}
|
|
3133
|
+
const checkVal = (12 - p) % 11;
|
|
3134
|
+
const checkChar = checkVal === 10 ? "X" : String(checkVal);
|
|
3135
|
+
if (compact[15].toUpperCase() !== checkChar)
|
|
3136
|
+
return { valid: false, error: `Check digit mismatch: expected ${checkChar}, got ${compact[15]}` };
|
|
3137
|
+
return { valid: true };
|
|
3138
|
+
}
|
|
3139
|
+
var ORCID_API_BASE = "https://pub.orcid.org/v3.0";
|
|
3140
|
+
var ORCID_HEADERS = { Accept: "application/vnd.orcid+json" };
|
|
3141
|
+
var ORCIDAdapter = {
|
|
3142
|
+
standardId: "orcid",
|
|
3143
|
+
uriScheme: "ORCID",
|
|
3144
|
+
normalize(value) {
|
|
3145
|
+
const clean = value.replace(/\s/g, "");
|
|
3146
|
+
if (clean.length === 16 && !clean.includes("-"))
|
|
3147
|
+
return `${clean.slice(0, 4)}-${clean.slice(4, 8)}-${clean.slice(8, 12)}-${clean.slice(12)}`;
|
|
3148
|
+
return clean;
|
|
3149
|
+
},
|
|
3150
|
+
display(value) {
|
|
3151
|
+
return ORCIDAdapter.normalize(value);
|
|
3152
|
+
},
|
|
3153
|
+
validate(value) {
|
|
3154
|
+
if (!value) return { valid: false, error: "ORCID iD is absent" };
|
|
3155
|
+
const normalized = ORCIDAdapter.normalize(value);
|
|
3156
|
+
if (!/^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$/.test(normalized))
|
|
3157
|
+
return { valid: false, error: `ORCID iD does not match pattern: ${normalized}` };
|
|
3158
|
+
return validateORCIDMod11_2(normalized.replace(/-/g, ""));
|
|
3159
|
+
},
|
|
3160
|
+
toLinkedDataUri(value) {
|
|
3161
|
+
return `https://orcid.org/${ORCIDAdapter.normalize(value)}`;
|
|
3162
|
+
},
|
|
3163
|
+
apis: {
|
|
3164
|
+
"orcid-lookup": {
|
|
3165
|
+
apiId: "orcid-lookup",
|
|
3166
|
+
name: "ORCID Public Record API",
|
|
3167
|
+
async fetch({ orcidId }) {
|
|
3168
|
+
if (!orcidId) return {};
|
|
3169
|
+
const res = await fetch(`${ORCID_API_BASE}/${orcidId}/record`, { headers: ORCID_HEADERS });
|
|
3170
|
+
if (!res.ok) return {};
|
|
3171
|
+
const data = await res.json();
|
|
3172
|
+
const person = data.person ?? {};
|
|
3173
|
+
const name = person.name ?? {};
|
|
3174
|
+
return {
|
|
3175
|
+
orcidId,
|
|
3176
|
+
givenNames: name["given-names"]?.value,
|
|
3177
|
+
familyName: name["family-name"]?.value,
|
|
3178
|
+
biography: person.biography?.content ?? void 0
|
|
3179
|
+
};
|
|
3180
|
+
}
|
|
3181
|
+
},
|
|
3182
|
+
"orcid-public-api": {
|
|
3183
|
+
apiId: "orcid-public-api",
|
|
3184
|
+
name: "ORCID Public Search API",
|
|
3185
|
+
async fetch({ orcidId }) {
|
|
3186
|
+
if (!orcidId) return [];
|
|
3187
|
+
const res = await fetch(
|
|
3188
|
+
`${ORCID_API_BASE}/search?q=orcid:${orcidId}&rows=10`,
|
|
3189
|
+
{ headers: ORCID_HEADERS }
|
|
3190
|
+
);
|
|
3191
|
+
if (!res.ok) return [];
|
|
3192
|
+
const data = await res.json();
|
|
3193
|
+
return (data.result ?? []).map((r) => {
|
|
3194
|
+
const item = r;
|
|
3195
|
+
const oid = item["orcid-identifier"]?.path;
|
|
3196
|
+
return { orcidId: oid ?? "" };
|
|
3197
|
+
}).filter((r) => r.orcidId);
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
};
|
|
3202
|
+
|
|
3203
|
+
// src/models/generated-src/Person.ts
|
|
3204
|
+
var schema = schemas["Person"];
|
|
3205
|
+
Registry.register(schema);
|
|
3206
|
+
var PERSON_PROP_IDS = { title: 0, description: 1, originalLang: 2, ageGradeBand: 3, previewTxId: 4, safe: 5, deleted: 6, lifecycleStatus: 7, birthDate: 43, deathDate: 44, nationality: 45, wikiUrl: 46, isniId: 47, orcidId: 48 };
|
|
3207
|
+
function serializePersonSlim(records) {
|
|
3208
|
+
return commonSerializeSlim(schema, records, currentLayout());
|
|
3209
|
+
}
|
|
3210
|
+
function serializePersonExtended(records) {
|
|
3211
|
+
return commonSerializeExtended(schema, records, currentLayout());
|
|
3212
|
+
}
|
|
3213
|
+
function serializePersonProv(records) {
|
|
3214
|
+
return commonSerializeProv(schema, records);
|
|
3215
|
+
}
|
|
3216
|
+
var _Person = class _Person extends Orm {
|
|
3217
|
+
constructor(json, creatorUsername) {
|
|
3218
|
+
super(_Person.type, json, creatorUsername);
|
|
3219
|
+
}
|
|
3220
|
+
/** Synchronous LRU read — throws on miss (use LoadAsync to re-hydrate). */
|
|
3221
|
+
static Load(id, creatorUsername) {
|
|
3222
|
+
return getRecord(_Person.type, id, creatorUsername);
|
|
3223
|
+
}
|
|
3224
|
+
static Has(id, creatorUsername) {
|
|
3225
|
+
return hasRecord(_Person.type, id, creatorUsername);
|
|
3226
|
+
}
|
|
3227
|
+
/** On-demand hydration from the worker after LRU eviction (SPEC §2.5). */
|
|
3228
|
+
static async LoadAsync(id, creatorUsername) {
|
|
3229
|
+
if (hasRecord(_Person.type, id, creatorUsername)) {
|
|
3230
|
+
return getRecord(_Person.type, id, creatorUsername);
|
|
3231
|
+
}
|
|
3232
|
+
const thread = PatchInstance.threadInstance;
|
|
3233
|
+
if (!thread) throw new Error("worker thread not initialized \u2014 call PatchInstance.initThread first");
|
|
3234
|
+
const res = await thread.sendRequest({
|
|
3235
|
+
cmd: "getRecord" /* GetRecord */,
|
|
3236
|
+
payload: { objectType: _Person.type, id }
|
|
3237
|
+
});
|
|
3238
|
+
if (!res || res.length === 0) throw new Error(`Person ${id} not found in worker storage`);
|
|
3239
|
+
const record = NewPersonWithId(id, creatorUsername);
|
|
3240
|
+
for (const data of res) {
|
|
3241
|
+
if (data.slim) record.mergeSlim(data.slim, 0, data.lang);
|
|
3242
|
+
if (data.extended) record.mergeExtended(data.extended, 0, data.lang);
|
|
3243
|
+
if (data.prov) record.mergeProv(data.prov, 0, data.lang);
|
|
3244
|
+
}
|
|
3245
|
+
return record;
|
|
3246
|
+
}
|
|
3247
|
+
get birthDate() {
|
|
3248
|
+
return this.getProp(43);
|
|
3249
|
+
}
|
|
3250
|
+
set birthDate(value) {
|
|
3251
|
+
this.dispatchString(43, value);
|
|
3252
|
+
}
|
|
3253
|
+
getBirthDate(lang) {
|
|
3254
|
+
return this.getProp(43, lang);
|
|
3255
|
+
}
|
|
3256
|
+
setBirthDate(value, lang) {
|
|
3257
|
+
this.dispatchString(43, value, lang);
|
|
3258
|
+
}
|
|
3259
|
+
get deathDate() {
|
|
3260
|
+
return this.getProp(44);
|
|
3261
|
+
}
|
|
3262
|
+
set deathDate(value) {
|
|
3263
|
+
this.dispatchString(44, value);
|
|
3264
|
+
}
|
|
3265
|
+
getDeathDate(lang) {
|
|
3266
|
+
return this.getProp(44, lang);
|
|
3267
|
+
}
|
|
3268
|
+
setDeathDate(value, lang) {
|
|
3269
|
+
this.dispatchString(44, value, lang);
|
|
3270
|
+
}
|
|
3271
|
+
get nationality() {
|
|
3272
|
+
return this.getProp(45);
|
|
3273
|
+
}
|
|
3274
|
+
set nationality(value) {
|
|
3275
|
+
this.dispatchString(45, value);
|
|
3276
|
+
}
|
|
3277
|
+
getNationality(lang) {
|
|
3278
|
+
return this.getProp(45, lang);
|
|
3279
|
+
}
|
|
3280
|
+
setNationality(value, lang) {
|
|
3281
|
+
this.dispatchString(45, value, lang);
|
|
3282
|
+
}
|
|
3283
|
+
get wikiUrl() {
|
|
3284
|
+
return this.getProp(46);
|
|
3285
|
+
}
|
|
3286
|
+
set wikiUrl(value) {
|
|
3287
|
+
this.dispatchString(46, value);
|
|
3288
|
+
}
|
|
3289
|
+
getWikiUrl(lang) {
|
|
3290
|
+
return this.getProp(46, lang);
|
|
3291
|
+
}
|
|
3292
|
+
setWikiUrl(value, lang) {
|
|
3293
|
+
this.dispatchString(46, value, lang);
|
|
3294
|
+
}
|
|
3295
|
+
get isniId() {
|
|
3296
|
+
return this.getProp(47) ?? null;
|
|
3297
|
+
}
|
|
3298
|
+
set isniId(value) {
|
|
3299
|
+
this.dispatchString(47, value ?? "");
|
|
3300
|
+
}
|
|
3301
|
+
getIsniId(lang) {
|
|
3302
|
+
return this.getProp(47, lang) ?? null;
|
|
3303
|
+
}
|
|
3304
|
+
setIsniId(value, lang) {
|
|
3305
|
+
this.dispatchString(47, value ?? "", lang);
|
|
3306
|
+
}
|
|
3307
|
+
get orcidId() {
|
|
3308
|
+
return this.getProp(48) ?? null;
|
|
3309
|
+
}
|
|
3310
|
+
set orcidId(value) {
|
|
3311
|
+
this.dispatchString(48, value ?? "");
|
|
3312
|
+
}
|
|
3313
|
+
getOrcidId(lang) {
|
|
3314
|
+
return this.getProp(48, lang) ?? null;
|
|
3315
|
+
}
|
|
3316
|
+
setOrcidId(value, lang) {
|
|
3317
|
+
this.dispatchString(48, value ?? "", lang);
|
|
3318
|
+
}
|
|
3319
|
+
get inAuthorOfIds() {
|
|
3320
|
+
return Array.from(this._in.get(2).values());
|
|
3321
|
+
}
|
|
3322
|
+
get inAuthorOf() {
|
|
3323
|
+
return this.inAuthorOfIds.map((id) => Book.Load(id));
|
|
3324
|
+
}
|
|
3325
|
+
isInAuthorOf(id) {
|
|
3326
|
+
return this._in.get(2).has(id);
|
|
3327
|
+
}
|
|
3328
|
+
addIntoAuthorOf(id) {
|
|
3329
|
+
if (this.isInAuthorOf(id)) return;
|
|
3330
|
+
const op = {
|
|
3331
|
+
operation: PatchOperation.EditRelation,
|
|
3332
|
+
objectType: Book.type,
|
|
3333
|
+
objectId: id,
|
|
3334
|
+
langId: 0,
|
|
3335
|
+
relationId: 1,
|
|
3336
|
+
// canonical: Book.authors
|
|
3337
|
+
action: PatchAction.Add,
|
|
3338
|
+
targetId: this.id
|
|
3339
|
+
};
|
|
3340
|
+
if (hasRecord(Book.type, id)) {
|
|
3341
|
+
getRecord(Book.type, id).patch(op);
|
|
3342
|
+
}
|
|
3343
|
+
this.applyRelationRaw("in", 2, PatchAction.Add, id);
|
|
3344
|
+
PatchInstance.addPatch(op);
|
|
3345
|
+
}
|
|
3346
|
+
removeFromAuthorOf(id) {
|
|
3347
|
+
if (!this.isInAuthorOf(id)) return;
|
|
3348
|
+
const op = {
|
|
3349
|
+
operation: PatchOperation.EditRelation,
|
|
3350
|
+
objectType: Book.type,
|
|
3351
|
+
objectId: id,
|
|
3352
|
+
langId: 0,
|
|
3353
|
+
relationId: 1,
|
|
3354
|
+
// canonical: Book.authors
|
|
3355
|
+
action: PatchAction.Remove,
|
|
3356
|
+
targetId: this.id
|
|
3357
|
+
};
|
|
3358
|
+
if (hasRecord(Book.type, id)) {
|
|
3359
|
+
getRecord(Book.type, id).patch(op);
|
|
3360
|
+
}
|
|
3361
|
+
this.applyRelationRaw("in", 2, PatchAction.Remove, id);
|
|
3362
|
+
PatchInstance.addPatch(op);
|
|
3363
|
+
}
|
|
3364
|
+
// ── UID methods ─────────────────────────────────────────────────────────
|
|
3365
|
+
toPID() {
|
|
3366
|
+
const scope = this.id & 2147483648 ? "U" : "C";
|
|
3367
|
+
return `DL:${scope}:PR:${encodePID("PR", this.id)}`;
|
|
3368
|
+
}
|
|
3369
|
+
toNativePID() {
|
|
3370
|
+
return this.toPID();
|
|
3371
|
+
}
|
|
3372
|
+
static fromPID(pid) {
|
|
3373
|
+
try {
|
|
3374
|
+
if (!pid.startsWith("DL:")) return decodePID("PR", pid);
|
|
3375
|
+
const parts = pid.split(":");
|
|
3376
|
+
if (parts.length >= 4 && parts[2] === "PR") {
|
|
3377
|
+
return decodePID("PR", parts[3]);
|
|
3378
|
+
}
|
|
3379
|
+
return null;
|
|
3380
|
+
} catch {
|
|
3381
|
+
return null;
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
// ── Inherited from isni standard ───────────────────────────────────────
|
|
3385
|
+
get isniNormalized() {
|
|
3386
|
+
return this.isniId ? ISNIAdapter.normalize(this.isniId) : null;
|
|
3387
|
+
}
|
|
3388
|
+
validateIsni() {
|
|
3389
|
+
return ISNIAdapter.validate(this.isniId);
|
|
3390
|
+
}
|
|
3391
|
+
// ── Inherited from orcid standard ───────────────────────────────────────
|
|
3392
|
+
get orcidNormalized() {
|
|
3393
|
+
return this.orcidId ? ORCIDAdapter.normalize(this.orcidId) : null;
|
|
3394
|
+
}
|
|
3395
|
+
validateOrcid() {
|
|
3396
|
+
return ORCIDAdapter.validate(this.orcidId);
|
|
3397
|
+
}
|
|
3398
|
+
sfcuid() {
|
|
3399
|
+
if (this.isniId) return `isni:${ISNIAdapter.normalize(this.isniId)}`;
|
|
3400
|
+
if (this.orcidId) return `orcid:${ORCIDAdapter.normalize(this.orcidId)}`;
|
|
3401
|
+
return this.toNativePID();
|
|
3402
|
+
}
|
|
3403
|
+
get identityCluster() {
|
|
3404
|
+
const primary = this.sfcuid();
|
|
3405
|
+
const allAliases = [
|
|
3406
|
+
this.isniId ? `isni:${ISNIAdapter.normalize(this.isniId)}` : null,
|
|
3407
|
+
this.orcidId ? `orcid:${ORCIDAdapter.normalize(this.orcidId)}` : null,
|
|
3408
|
+
this.toNativePID()
|
|
3409
|
+
].filter(Boolean);
|
|
3410
|
+
return {
|
|
3411
|
+
sfcuid: primary,
|
|
3412
|
+
native: this.toNativePID(),
|
|
3413
|
+
aliases: allAliases.filter((a) => a !== primary),
|
|
3414
|
+
wireId: this.id
|
|
3415
|
+
};
|
|
3416
|
+
}
|
|
3417
|
+
// Merge methods are now implemented in Orm using the schema definition.
|
|
3418
|
+
};
|
|
3419
|
+
_Person.type = 1;
|
|
3420
|
+
_Person.UID_STRATEGY = "standards-first";
|
|
3421
|
+
_Person.STANDARD_PRIORITY = ["isni", "orcid"];
|
|
3422
|
+
_Person.serializeSlim = serializePersonSlim;
|
|
3423
|
+
_Person.serializeExtended = serializePersonExtended;
|
|
3424
|
+
_Person.serializeProv = serializePersonProv;
|
|
3425
|
+
var Person = _Person;
|
|
3426
|
+
var NewPersonWithId = (id, creatorUsername) => {
|
|
3427
|
+
if (hasRecord(Person.type, id, creatorUsername)) {
|
|
3428
|
+
return getRecord(Person.type, id, creatorUsername);
|
|
3429
|
+
}
|
|
3430
|
+
const record = new Person(Person.createNewRequest(id), creatorUsername);
|
|
3431
|
+
addRecord(Person.type, record, creatorUsername);
|
|
3432
|
+
return record;
|
|
3433
|
+
};
|
|
3434
|
+
|
|
3435
|
+
// ../standard-adapters/dist/chunk-VP4ER7MD.js
|
|
3436
|
+
var LCCAdapter = {
|
|
3437
|
+
standardId: "lcc",
|
|
3438
|
+
uriScheme: "LCC",
|
|
3439
|
+
normalize(value) {
|
|
3440
|
+
return value.trim();
|
|
3441
|
+
},
|
|
3442
|
+
display(value) {
|
|
3443
|
+
return LCCAdapter.normalize(value);
|
|
3444
|
+
},
|
|
3445
|
+
validate(value) {
|
|
3446
|
+
if (!value) return { valid: false, error: "LCC notation is absent" };
|
|
3447
|
+
const normalized = LCCAdapter.normalize(value);
|
|
3448
|
+
if (!/^[A-Z0-9\.\s]+$/.test(normalized))
|
|
3449
|
+
return { valid: false, error: `LCC notation does not match pattern: ${normalized}` };
|
|
3450
|
+
return { valid: true };
|
|
3451
|
+
},
|
|
3452
|
+
toLinkedDataUri(value) {
|
|
3453
|
+
return `https://id.loc.gov/authorities/classification/${LCCAdapter.normalize(value)}`;
|
|
3454
|
+
},
|
|
3455
|
+
apis: {}
|
|
3456
|
+
};
|
|
3457
|
+
|
|
3458
|
+
// ../standard-adapters/dist/chunk-AHIDYNLW.js
|
|
3459
|
+
var DDCAdapter = {
|
|
3460
|
+
standardId: "ddc",
|
|
3461
|
+
uriScheme: "DDC",
|
|
3462
|
+
normalize(value) {
|
|
3463
|
+
let trimmed = value.trim();
|
|
3464
|
+
if (trimmed.includes(".")) trimmed = trimmed.replace(/\.?0+$/, "");
|
|
3465
|
+
return trimmed;
|
|
3466
|
+
},
|
|
3467
|
+
display(value) {
|
|
3468
|
+
return DDCAdapter.normalize(value);
|
|
3469
|
+
},
|
|
3470
|
+
validate(value) {
|
|
3471
|
+
if (!value) return { valid: false, error: "DDC notation is absent" };
|
|
3472
|
+
const normalized = DDCAdapter.normalize(value);
|
|
3473
|
+
if (!/^[0-9]{3}(\.[0-9]+)?$/.test(normalized))
|
|
3474
|
+
return { valid: false, error: `DDC notation does not match pattern: ${normalized}` };
|
|
3475
|
+
return { valid: true };
|
|
3476
|
+
},
|
|
3477
|
+
toLinkedDataUri(value) {
|
|
3478
|
+
return `https://id.loc.gov/authorities/classification/${DDCAdapter.normalize(value)}`;
|
|
3479
|
+
},
|
|
3480
|
+
apis: {}
|
|
3481
|
+
};
|
|
3482
|
+
|
|
3483
|
+
// ../standard-adapters/dist/chunk-C5WHAJXI.js
|
|
3484
|
+
var UDCAdapter = {
|
|
3485
|
+
standardId: "udc",
|
|
3486
|
+
uriScheme: "UDC",
|
|
3487
|
+
normalize(value) {
|
|
3488
|
+
return value.trim();
|
|
3489
|
+
},
|
|
3490
|
+
display(value) {
|
|
3491
|
+
return UDCAdapter.normalize(value);
|
|
3492
|
+
},
|
|
3493
|
+
validate(value) {
|
|
3494
|
+
if (!value) return { valid: false, error: "UDC notation is absent" };
|
|
3495
|
+
const normalized = UDCAdapter.normalize(value);
|
|
3496
|
+
if (!/^[0-9\.\-\:\+\/\(\)\[\]\=\*\"\s]+$/.test(normalized))
|
|
3497
|
+
return { valid: false, error: `UDC notation does not match pattern: ${normalized}` };
|
|
3498
|
+
return { valid: true };
|
|
3499
|
+
},
|
|
3500
|
+
toLinkedDataUri(value) {
|
|
3501
|
+
return `https://udcsummary.info/php/index.php?c=${UDCAdapter.normalize(value)}`;
|
|
3502
|
+
},
|
|
3503
|
+
apis: {}
|
|
3504
|
+
};
|
|
3505
|
+
|
|
3506
|
+
// ../standard-adapters/dist/chunk-IJYCM5NU.js
|
|
3507
|
+
var CLCAdapter = {
|
|
3508
|
+
standardId: "clc",
|
|
3509
|
+
uriScheme: "CLC",
|
|
3510
|
+
normalize(value) {
|
|
3511
|
+
return value.trim();
|
|
3512
|
+
},
|
|
3513
|
+
display(value) {
|
|
3514
|
+
return CLCAdapter.normalize(value);
|
|
3515
|
+
},
|
|
3516
|
+
validate(value) {
|
|
3517
|
+
if (!value) return { valid: false, error: "CLC notation is absent" };
|
|
3518
|
+
const normalized = CLCAdapter.normalize(value);
|
|
3519
|
+
if (!/^[A-Z0-9\.\-\+\=\s]+$/.test(normalized))
|
|
3520
|
+
return { valid: false, error: `CLC notation does not match pattern: ${normalized}` };
|
|
3521
|
+
return { valid: true };
|
|
3522
|
+
},
|
|
3523
|
+
toLinkedDataUri(value) {
|
|
3524
|
+
return `https://clc.nlc.cn/${CLCAdapter.normalize(value)}`;
|
|
3525
|
+
},
|
|
3526
|
+
apis: {}
|
|
3527
|
+
};
|
|
3528
|
+
|
|
3529
|
+
// ../standard-adapters/dist/chunk-INW2BUCX.js
|
|
3530
|
+
var BBKAdapter = {
|
|
3531
|
+
standardId: "bbk",
|
|
3532
|
+
uriScheme: "BBK",
|
|
3533
|
+
normalize(value) {
|
|
3534
|
+
return value.trim();
|
|
3535
|
+
},
|
|
3536
|
+
display(value) {
|
|
3537
|
+
return BBKAdapter.normalize(value);
|
|
3538
|
+
},
|
|
3539
|
+
validate(value) {
|
|
3540
|
+
if (!value) return { valid: false, error: "BBK notation is absent" };
|
|
3541
|
+
const normalized = BBKAdapter.normalize(value);
|
|
3542
|
+
if (!/^[0-9А-Яа-яA-Za-z\.\-\s]+$/.test(normalized))
|
|
3543
|
+
return { valid: false, error: `BBK notation does not match pattern: ${normalized}` };
|
|
3544
|
+
return { valid: true };
|
|
3545
|
+
},
|
|
3546
|
+
toLinkedDataUri(value) {
|
|
3547
|
+
return `https://bbk.rsl.ru/external/${BBKAdapter.normalize(value)}`;
|
|
3548
|
+
},
|
|
3549
|
+
apis: {}
|
|
3550
|
+
};
|
|
3551
|
+
|
|
3552
|
+
// ../standard-adapters/dist/chunk-D5QOJWWA.js
|
|
3553
|
+
var TLCAdapter = {
|
|
3554
|
+
standardId: "tlc",
|
|
3555
|
+
uriScheme: "TLC",
|
|
3556
|
+
normalize(value) {
|
|
3557
|
+
return value.trim();
|
|
3558
|
+
},
|
|
3559
|
+
display(value) {
|
|
3560
|
+
return TLCAdapter.normalize(value);
|
|
3561
|
+
},
|
|
3562
|
+
validate(value) {
|
|
3563
|
+
if (!value) return { valid: false, error: "TLC notation is absent" };
|
|
3564
|
+
const normalized = TLCAdapter.normalize(value);
|
|
3565
|
+
if (!/^[A-Z0-9\.\-\s]+$/.test(normalized))
|
|
3566
|
+
return { valid: false, error: `TLC notation does not match pattern: ${normalized}` };
|
|
3567
|
+
return { valid: true };
|
|
3568
|
+
},
|
|
3569
|
+
toLinkedDataUri(value) {
|
|
3570
|
+
return `https://nlt.go.th/tlc/${TLCAdapter.normalize(value)}`;
|
|
3571
|
+
},
|
|
3572
|
+
apis: {}
|
|
3573
|
+
};
|
|
3574
|
+
|
|
3575
|
+
// ../standard-adapters/dist/chunk-KOHT5EA3.js
|
|
3576
|
+
var CCAdapter = {
|
|
3577
|
+
standardId: "cc",
|
|
3578
|
+
uriScheme: "CC",
|
|
3579
|
+
normalize(value) {
|
|
3580
|
+
return value.trim();
|
|
3581
|
+
},
|
|
3582
|
+
display(value) {
|
|
3583
|
+
return CCAdapter.normalize(value);
|
|
3584
|
+
},
|
|
3585
|
+
validate(value) {
|
|
3586
|
+
if (!value) return { valid: false, error: "CC notation is absent" };
|
|
3587
|
+
const normalized = CCAdapter.normalize(value);
|
|
3588
|
+
if (!/^[A-Za-z0-9\:\,\;\-\.\'\s]+$/.test(normalized))
|
|
3589
|
+
return { valid: false, error: `CC notation does not match pattern: ${normalized}` };
|
|
3590
|
+
return { valid: true };
|
|
3591
|
+
},
|
|
3592
|
+
toLinkedDataUri(value) {
|
|
3593
|
+
return `https://isko.org/cc/${CCAdapter.normalize(value)}`;
|
|
3594
|
+
},
|
|
3595
|
+
apis: {}
|
|
3596
|
+
};
|
|
3597
|
+
|
|
3598
|
+
// src/models/generated-src/Tag.ts
|
|
3599
|
+
var schema2 = schemas["Tag"];
|
|
3600
|
+
Registry.register(schema2);
|
|
3601
|
+
var TAG_PROP_IDS = { title: 0, description: 1, originalLang: 2, ageGradeBand: 3, previewTxId: 4, safe: 5, deleted: 6, lifecycleStatus: 7, lccNotation: 50, ddcNotation: 49, udcNotation: 51, clcNotation: 52, bbkNotation: 53, tlcNotation: 54, ccNotation: 55 };
|
|
3602
|
+
function serializeTagSlim(records) {
|
|
3603
|
+
return commonSerializeSlim(schema2, records, currentLayout());
|
|
3604
|
+
}
|
|
3605
|
+
function serializeTagExtended(records) {
|
|
3606
|
+
return commonSerializeExtended(schema2, records, currentLayout());
|
|
3607
|
+
}
|
|
3608
|
+
function serializeTagProv(records) {
|
|
3609
|
+
return commonSerializeProv(schema2, records);
|
|
3610
|
+
}
|
|
3611
|
+
var _Tag = class _Tag extends Orm {
|
|
3612
|
+
constructor(json, creatorUsername) {
|
|
3613
|
+
super(_Tag.type, json, creatorUsername);
|
|
3614
|
+
}
|
|
3615
|
+
/** Synchronous LRU read — throws on miss (use LoadAsync to re-hydrate). */
|
|
3616
|
+
static Load(id, creatorUsername) {
|
|
3617
|
+
return getRecord(_Tag.type, id, creatorUsername);
|
|
3618
|
+
}
|
|
3619
|
+
static Has(id, creatorUsername) {
|
|
3620
|
+
return hasRecord(_Tag.type, id, creatorUsername);
|
|
3621
|
+
}
|
|
3622
|
+
/** On-demand hydration from the worker after LRU eviction (SPEC §2.5). */
|
|
3623
|
+
static async LoadAsync(id, creatorUsername) {
|
|
3624
|
+
if (hasRecord(_Tag.type, id, creatorUsername)) {
|
|
3625
|
+
return getRecord(_Tag.type, id, creatorUsername);
|
|
3626
|
+
}
|
|
3627
|
+
const thread = PatchInstance.threadInstance;
|
|
3628
|
+
if (!thread) throw new Error("worker thread not initialized \u2014 call PatchInstance.initThread first");
|
|
3629
|
+
const res = await thread.sendRequest({
|
|
3630
|
+
cmd: "getRecord" /* GetRecord */,
|
|
3631
|
+
payload: { objectType: _Tag.type, id }
|
|
3632
|
+
});
|
|
3633
|
+
if (!res || res.length === 0) throw new Error(`Tag ${id} not found in worker storage`);
|
|
3634
|
+
const record = NewTagWithId(id, creatorUsername);
|
|
3635
|
+
for (const data of res) {
|
|
3636
|
+
if (data.slim) record.mergeSlim(data.slim, 0, data.lang);
|
|
3637
|
+
if (data.extended) record.mergeExtended(data.extended, 0, data.lang);
|
|
3638
|
+
if (data.prov) record.mergeProv(data.prov, 0, data.lang);
|
|
3639
|
+
}
|
|
3640
|
+
return record;
|
|
3641
|
+
}
|
|
3642
|
+
get lccNotation() {
|
|
3643
|
+
return this.getProp(50) ?? null;
|
|
3644
|
+
}
|
|
3645
|
+
set lccNotation(value) {
|
|
3646
|
+
this.dispatchString(50, value ?? "");
|
|
3647
|
+
}
|
|
3648
|
+
getLccNotation(lang) {
|
|
3649
|
+
return this.getProp(50, lang) ?? null;
|
|
3650
|
+
}
|
|
3651
|
+
setLccNotation(value, lang) {
|
|
3652
|
+
this.dispatchString(50, value ?? "", lang);
|
|
3653
|
+
}
|
|
3654
|
+
get ddcNotation() {
|
|
3655
|
+
return this.getProp(49) ?? null;
|
|
3656
|
+
}
|
|
3657
|
+
set ddcNotation(value) {
|
|
3658
|
+
this.dispatchString(49, value ?? "");
|
|
3659
|
+
}
|
|
3660
|
+
getDdcNotation(lang) {
|
|
3661
|
+
return this.getProp(49, lang) ?? null;
|
|
3662
|
+
}
|
|
3663
|
+
setDdcNotation(value, lang) {
|
|
3664
|
+
this.dispatchString(49, value ?? "", lang);
|
|
3665
|
+
}
|
|
3666
|
+
get udcNotation() {
|
|
3667
|
+
return this.getProp(51) ?? null;
|
|
3668
|
+
}
|
|
3669
|
+
set udcNotation(value) {
|
|
3670
|
+
this.dispatchString(51, value ?? "");
|
|
3671
|
+
}
|
|
3672
|
+
getUdcNotation(lang) {
|
|
3673
|
+
return this.getProp(51, lang) ?? null;
|
|
3674
|
+
}
|
|
3675
|
+
setUdcNotation(value, lang) {
|
|
3676
|
+
this.dispatchString(51, value ?? "", lang);
|
|
3677
|
+
}
|
|
3678
|
+
get clcNotation() {
|
|
3679
|
+
return this.getProp(52) ?? null;
|
|
3680
|
+
}
|
|
3681
|
+
set clcNotation(value) {
|
|
3682
|
+
this.dispatchString(52, value ?? "");
|
|
3683
|
+
}
|
|
3684
|
+
getClcNotation(lang) {
|
|
3685
|
+
return this.getProp(52, lang) ?? null;
|
|
3686
|
+
}
|
|
3687
|
+
setClcNotation(value, lang) {
|
|
3688
|
+
this.dispatchString(52, value ?? "", lang);
|
|
3689
|
+
}
|
|
3690
|
+
get bbkNotation() {
|
|
3691
|
+
return this.getProp(53) ?? null;
|
|
3692
|
+
}
|
|
3693
|
+
set bbkNotation(value) {
|
|
3694
|
+
this.dispatchString(53, value ?? "");
|
|
3695
|
+
}
|
|
3696
|
+
getBbkNotation(lang) {
|
|
3697
|
+
return this.getProp(53, lang) ?? null;
|
|
3698
|
+
}
|
|
3699
|
+
setBbkNotation(value, lang) {
|
|
3700
|
+
this.dispatchString(53, value ?? "", lang);
|
|
3701
|
+
}
|
|
3702
|
+
get tlcNotation() {
|
|
3703
|
+
return this.getProp(54) ?? null;
|
|
3704
|
+
}
|
|
3705
|
+
set tlcNotation(value) {
|
|
3706
|
+
this.dispatchString(54, value ?? "");
|
|
3707
|
+
}
|
|
3708
|
+
getTlcNotation(lang) {
|
|
3709
|
+
return this.getProp(54, lang) ?? null;
|
|
3710
|
+
}
|
|
3711
|
+
setTlcNotation(value, lang) {
|
|
3712
|
+
this.dispatchString(54, value ?? "", lang);
|
|
3713
|
+
}
|
|
3714
|
+
get ccNotation() {
|
|
3715
|
+
return this.getProp(55) ?? null;
|
|
3716
|
+
}
|
|
3717
|
+
set ccNotation(value) {
|
|
3718
|
+
this.dispatchString(55, value ?? "");
|
|
3719
|
+
}
|
|
3720
|
+
getCcNotation(lang) {
|
|
3721
|
+
return this.getProp(55, lang) ?? null;
|
|
3722
|
+
}
|
|
3723
|
+
setCcNotation(value, lang) {
|
|
3724
|
+
this.dispatchString(55, value ?? "", lang);
|
|
3725
|
+
}
|
|
3726
|
+
get inTagsIds() {
|
|
3727
|
+
return Array.from(this._in.get(0).values());
|
|
3728
|
+
}
|
|
3729
|
+
get inTags() {
|
|
3730
|
+
return this.inTagsIds.map((id) => _Tag.Load(id));
|
|
3731
|
+
}
|
|
3732
|
+
isInTag(id) {
|
|
3733
|
+
return this._in.get(0).has(id);
|
|
3734
|
+
}
|
|
3735
|
+
addIntoTag(id) {
|
|
3736
|
+
if (this.isInTag(id)) return;
|
|
3737
|
+
const op = {
|
|
3738
|
+
operation: PatchOperation.EditRelation,
|
|
3739
|
+
objectType: _Tag.type,
|
|
3740
|
+
objectId: id,
|
|
3741
|
+
langId: 0,
|
|
3742
|
+
relationId: 3,
|
|
3743
|
+
// canonical: Tag.tags
|
|
3744
|
+
action: PatchAction.Add,
|
|
3745
|
+
targetId: this.id
|
|
3746
|
+
};
|
|
3747
|
+
if (hasRecord(_Tag.type, id)) {
|
|
3748
|
+
getRecord(_Tag.type, id).patch(op);
|
|
3749
|
+
}
|
|
3750
|
+
this.applyRelationRaw("in", 0, PatchAction.Add, id);
|
|
3751
|
+
PatchInstance.addPatch(op);
|
|
3752
|
+
}
|
|
3753
|
+
removeFromTag(id) {
|
|
3754
|
+
if (!this.isInTag(id)) return;
|
|
3755
|
+
const op = {
|
|
3756
|
+
operation: PatchOperation.EditRelation,
|
|
3757
|
+
objectType: _Tag.type,
|
|
3758
|
+
objectId: id,
|
|
3759
|
+
langId: 0,
|
|
3760
|
+
relationId: 3,
|
|
3761
|
+
// canonical: Tag.tags
|
|
3762
|
+
action: PatchAction.Remove,
|
|
3763
|
+
targetId: this.id
|
|
3764
|
+
};
|
|
3765
|
+
if (hasRecord(_Tag.type, id)) {
|
|
3766
|
+
getRecord(_Tag.type, id).patch(op);
|
|
3767
|
+
}
|
|
3768
|
+
this.applyRelationRaw("in", 0, PatchAction.Remove, id);
|
|
3769
|
+
PatchInstance.addPatch(op);
|
|
3770
|
+
}
|
|
3771
|
+
get tagsIds() {
|
|
3772
|
+
return Array.from(this._has.get(3).values());
|
|
3773
|
+
}
|
|
3774
|
+
get tags() {
|
|
3775
|
+
return this.tagsIds.map((id) => _Tag.Load(id));
|
|
3776
|
+
}
|
|
3777
|
+
hasTag(id) {
|
|
3778
|
+
return this._has.get(3).has(id);
|
|
3779
|
+
}
|
|
3780
|
+
addTag(id) {
|
|
3781
|
+
if (this.hasTag(id)) return;
|
|
3782
|
+
this.dispatchRelation(3, PatchAction.Add, id);
|
|
3783
|
+
}
|
|
3784
|
+
removeTag(id) {
|
|
3785
|
+
if (!this.hasTag(id)) return;
|
|
3786
|
+
this.dispatchRelation(3, PatchAction.Remove, id);
|
|
3787
|
+
}
|
|
3788
|
+
get booksIds() {
|
|
3789
|
+
return Array.from(this._has.get(4).values());
|
|
3790
|
+
}
|
|
3791
|
+
get books() {
|
|
3792
|
+
return this.booksIds.map((id) => Book.Load(id));
|
|
3793
|
+
}
|
|
3794
|
+
hasBook(id) {
|
|
3795
|
+
return this._has.get(4).has(id);
|
|
3796
|
+
}
|
|
3797
|
+
addBook(id) {
|
|
3798
|
+
if (this.hasBook(id)) return;
|
|
3799
|
+
this.dispatchRelation(4, PatchAction.Add, id);
|
|
3800
|
+
}
|
|
3801
|
+
removeBook(id) {
|
|
3802
|
+
if (!this.hasBook(id)) return;
|
|
3803
|
+
this.dispatchRelation(4, PatchAction.Remove, id);
|
|
3804
|
+
}
|
|
3805
|
+
// ── UID methods ─────────────────────────────────────────────────────────
|
|
3806
|
+
toPID() {
|
|
3807
|
+
const scope = this.id & 2147483648 ? "U" : "C";
|
|
3808
|
+
return `DL:${scope}:TG:${encodePID("TG", this.id)}`;
|
|
3809
|
+
}
|
|
3810
|
+
toNativePID() {
|
|
3811
|
+
return this.toPID();
|
|
3812
|
+
}
|
|
3813
|
+
static fromPID(pid) {
|
|
3814
|
+
try {
|
|
3815
|
+
if (!pid.startsWith("DL:")) return decodePID("TG", pid);
|
|
3816
|
+
const parts = pid.split(":");
|
|
3817
|
+
if (parts.length >= 4 && parts[2] === "TG") {
|
|
3818
|
+
return decodePID("TG", parts[3]);
|
|
3819
|
+
}
|
|
3820
|
+
return null;
|
|
3821
|
+
} catch {
|
|
3822
|
+
return null;
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
// ── Inherited from lcc standard ───────────────────────────────────────
|
|
3826
|
+
get lccNormalized() {
|
|
3827
|
+
return this.lccNotation ? LCCAdapter.normalize(this.lccNotation) : null;
|
|
3828
|
+
}
|
|
3829
|
+
validateLcc() {
|
|
3830
|
+
return LCCAdapter.validate(this.lccNotation);
|
|
3831
|
+
}
|
|
3832
|
+
// ── Inherited from ddc standard ───────────────────────────────────────
|
|
3833
|
+
get ddcNormalized() {
|
|
3834
|
+
return this.ddcNotation ? DDCAdapter.normalize(this.ddcNotation) : null;
|
|
3835
|
+
}
|
|
3836
|
+
validateDdc() {
|
|
3837
|
+
return DDCAdapter.validate(this.ddcNotation);
|
|
3838
|
+
}
|
|
3839
|
+
// ── Inherited from udc standard ───────────────────────────────────────
|
|
3840
|
+
get udcNormalized() {
|
|
3841
|
+
return this.udcNotation ? UDCAdapter.normalize(this.udcNotation) : null;
|
|
3842
|
+
}
|
|
3843
|
+
validateUdc() {
|
|
3844
|
+
return UDCAdapter.validate(this.udcNotation);
|
|
3845
|
+
}
|
|
3846
|
+
// ── Inherited from clc standard ───────────────────────────────────────
|
|
3847
|
+
get clcNormalized() {
|
|
3848
|
+
return this.clcNotation ? CLCAdapter.normalize(this.clcNotation) : null;
|
|
3849
|
+
}
|
|
3850
|
+
validateClc() {
|
|
3851
|
+
return CLCAdapter.validate(this.clcNotation);
|
|
3852
|
+
}
|
|
3853
|
+
// ── Inherited from bbk standard ───────────────────────────────────────
|
|
3854
|
+
get bbkNormalized() {
|
|
3855
|
+
return this.bbkNotation ? BBKAdapter.normalize(this.bbkNotation) : null;
|
|
3856
|
+
}
|
|
3857
|
+
validateBbk() {
|
|
3858
|
+
return BBKAdapter.validate(this.bbkNotation);
|
|
3859
|
+
}
|
|
3860
|
+
// ── Inherited from tlc standard ───────────────────────────────────────
|
|
3861
|
+
get tlcNormalized() {
|
|
3862
|
+
return this.tlcNotation ? TLCAdapter.normalize(this.tlcNotation) : null;
|
|
3863
|
+
}
|
|
3864
|
+
validateTlc() {
|
|
3865
|
+
return TLCAdapter.validate(this.tlcNotation);
|
|
3866
|
+
}
|
|
3867
|
+
// ── Inherited from cc standard ───────────────────────────────────────
|
|
3868
|
+
get ccNormalized() {
|
|
3869
|
+
return this.ccNotation ? CCAdapter.normalize(this.ccNotation) : null;
|
|
3870
|
+
}
|
|
3871
|
+
validateCc() {
|
|
3872
|
+
return CCAdapter.validate(this.ccNotation);
|
|
3873
|
+
}
|
|
3874
|
+
sfcuid() {
|
|
3875
|
+
if (this.lccNotation) return `lcc:${LCCAdapter.normalize(this.lccNotation)}`;
|
|
3876
|
+
if (this.ddcNotation) return `ddc:${DDCAdapter.normalize(this.ddcNotation)}`;
|
|
3877
|
+
if (this.udcNotation) return `udc:${UDCAdapter.normalize(this.udcNotation)}`;
|
|
3878
|
+
if (this.clcNotation) return `clc:${CLCAdapter.normalize(this.clcNotation)}`;
|
|
3879
|
+
if (this.bbkNotation) return `bbk:${BBKAdapter.normalize(this.bbkNotation)}`;
|
|
3880
|
+
if (this.tlcNotation) return `tlc:${TLCAdapter.normalize(this.tlcNotation)}`;
|
|
3881
|
+
if (this.ccNotation) return `cc:${CCAdapter.normalize(this.ccNotation)}`;
|
|
3882
|
+
return this.toNativePID();
|
|
3883
|
+
}
|
|
3884
|
+
get identityCluster() {
|
|
3885
|
+
const primary = this.sfcuid();
|
|
3886
|
+
const allAliases = [
|
|
3887
|
+
this.lccNotation ? `lcc:${LCCAdapter.normalize(this.lccNotation)}` : null,
|
|
3888
|
+
this.ddcNotation ? `ddc:${DDCAdapter.normalize(this.ddcNotation)}` : null,
|
|
3889
|
+
this.udcNotation ? `udc:${UDCAdapter.normalize(this.udcNotation)}` : null,
|
|
3890
|
+
this.clcNotation ? `clc:${CLCAdapter.normalize(this.clcNotation)}` : null,
|
|
3891
|
+
this.bbkNotation ? `bbk:${BBKAdapter.normalize(this.bbkNotation)}` : null,
|
|
3892
|
+
this.tlcNotation ? `tlc:${TLCAdapter.normalize(this.tlcNotation)}` : null,
|
|
3893
|
+
this.ccNotation ? `cc:${CCAdapter.normalize(this.ccNotation)}` : null,
|
|
3894
|
+
this.toNativePID()
|
|
3895
|
+
].filter(Boolean);
|
|
3896
|
+
return {
|
|
3897
|
+
sfcuid: primary,
|
|
3898
|
+
native: this.toNativePID(),
|
|
3899
|
+
aliases: allAliases.filter((a) => a !== primary),
|
|
3900
|
+
wireId: this.id
|
|
3901
|
+
};
|
|
3902
|
+
}
|
|
3903
|
+
// Merge methods are now implemented in Orm using the schema definition.
|
|
3904
|
+
};
|
|
3905
|
+
_Tag.type = 2;
|
|
3906
|
+
_Tag.UID_STRATEGY = "standards-first";
|
|
3907
|
+
_Tag.STANDARD_PRIORITY = ["lcc", "ddc", "udc", "clc", "bbk", "tlc", "cc"];
|
|
3908
|
+
_Tag.serializeSlim = serializeTagSlim;
|
|
3909
|
+
_Tag.serializeExtended = serializeTagExtended;
|
|
3910
|
+
_Tag.serializeProv = serializeTagProv;
|
|
3911
|
+
var Tag = _Tag;
|
|
3912
|
+
var NewTagWithId = (id, creatorUsername) => {
|
|
3913
|
+
if (hasRecord(Tag.type, id, creatorUsername)) {
|
|
3914
|
+
return getRecord(Tag.type, id, creatorUsername);
|
|
3915
|
+
}
|
|
3916
|
+
const record = new Tag(Tag.createNewRequest(id), creatorUsername);
|
|
3917
|
+
addRecord(Tag.type, record, creatorUsername);
|
|
3918
|
+
return record;
|
|
3919
|
+
};
|
|
3920
|
+
|
|
3921
|
+
// ../standard-adapters/dist/chunk-3OK4JVCA.js
|
|
3922
|
+
var _keys = /* @__PURE__ */ new Map();
|
|
3923
|
+
var apiKeyDictionary = {
|
|
3924
|
+
set(apiId, value) {
|
|
3925
|
+
if (!value) throw new Error(`[apiKeyDictionary] Empty value passed for apiId "${apiId}".`);
|
|
3926
|
+
_keys.set(apiId, value);
|
|
3927
|
+
},
|
|
3928
|
+
get(apiId) {
|
|
3929
|
+
return _keys.get(apiId);
|
|
3930
|
+
},
|
|
3931
|
+
require(apiId) {
|
|
3932
|
+
const key = _keys.get(apiId);
|
|
3933
|
+
if (!key) throw new Error(
|
|
3934
|
+
`[${apiId}] API key is not configured. Call apiKeyDictionary.set("${apiId}", "<your-key>") before using this adapter.`
|
|
3935
|
+
);
|
|
3936
|
+
return key;
|
|
3937
|
+
}
|
|
3938
|
+
};
|
|
3939
|
+
function validateISBN13Luhn(isbn13) {
|
|
3940
|
+
if (isbn13.length !== 13) return { valid: false, error: `Expected 13 digits, got ${isbn13.length}` };
|
|
3941
|
+
let sum = 0;
|
|
3942
|
+
for (let i = 0; i < 12; i++) sum += parseInt(isbn13[i], 10) * (i % 2 === 0 ? 1 : 3);
|
|
3943
|
+
const expected = (10 - sum % 10) % 10;
|
|
3944
|
+
if (expected !== parseInt(isbn13[12], 10))
|
|
3945
|
+
return { valid: false, error: `Check digit mismatch: expected ${expected}, got ${isbn13[12]}` };
|
|
3946
|
+
return { valid: true };
|
|
3947
|
+
}
|
|
3948
|
+
var ISBNAdapter = {
|
|
3949
|
+
standardId: "isbn",
|
|
3950
|
+
uriScheme: "ISBN",
|
|
3951
|
+
normalize(value) {
|
|
3952
|
+
const digits = value.replace(/[\s-]/g, "");
|
|
3953
|
+
if (digits.length === 10) {
|
|
3954
|
+
const base = "978" + digits.slice(0, 9);
|
|
3955
|
+
let sum = 0;
|
|
3956
|
+
for (let i = 0; i < 12; i++) sum += parseInt(base[i], 10) * (i % 2 === 0 ? 1 : 3);
|
|
3957
|
+
return base + (10 - sum % 10) % 10;
|
|
3958
|
+
}
|
|
3959
|
+
return digits;
|
|
3960
|
+
},
|
|
3961
|
+
display(value) {
|
|
3962
|
+
const n = ISBNAdapter.normalize(value);
|
|
3963
|
+
if (n.length === 13) return `${n.slice(0, 3)}-${n[3]}-${n.slice(4, 7)}-${n.slice(7, 12)}-${n[12]}`;
|
|
3964
|
+
return n;
|
|
3965
|
+
},
|
|
3966
|
+
validate(value) {
|
|
3967
|
+
if (!value) return { valid: false, error: "ISBN is absent" };
|
|
3968
|
+
const normalized = ISBNAdapter.normalize(value);
|
|
3969
|
+
if (!/^97[89][0-9]{10}$/.test(normalized))
|
|
3970
|
+
return { valid: false, error: `ISBN does not match pattern: ${normalized}` };
|
|
3971
|
+
return validateISBN13Luhn(normalized);
|
|
3972
|
+
},
|
|
3973
|
+
toLinkedDataUri(value) {
|
|
3974
|
+
return `urn:isbn:${ISBNAdapter.normalize(value)}`;
|
|
3975
|
+
},
|
|
3976
|
+
apis: {
|
|
3977
|
+
openlibrary: {
|
|
3978
|
+
apiId: "openlibrary",
|
|
3979
|
+
name: "Open Library Books API",
|
|
3980
|
+
async fetch({ isbn }) {
|
|
3981
|
+
if (!isbn) return {};
|
|
3982
|
+
const res = await fetch(
|
|
3983
|
+
`https://openlibrary.org/api/books?bibkeys=ISBN:${isbn}&format=json&jscmd=data`
|
|
3984
|
+
);
|
|
3985
|
+
if (!res.ok) return {};
|
|
3986
|
+
const data = await res.json();
|
|
3987
|
+
const book = data[`ISBN:${isbn}`] ?? {};
|
|
3988
|
+
return {
|
|
3989
|
+
title: book.title,
|
|
3990
|
+
authors: book.authors?.map((a) => a.name),
|
|
3991
|
+
publishDate: book.publish_date,
|
|
3992
|
+
pageCount: book.number_of_pages,
|
|
3993
|
+
coverUrl: book.cover?.medium,
|
|
3994
|
+
description: book.excerpts?.[0]?.text
|
|
3995
|
+
};
|
|
3996
|
+
}
|
|
3997
|
+
},
|
|
3998
|
+
googlebooks: {
|
|
3999
|
+
apiId: "googlebooks",
|
|
4000
|
+
name: "Google Books API",
|
|
4001
|
+
async fetch({ isbn }) {
|
|
4002
|
+
if (!isbn) return {};
|
|
4003
|
+
const key = apiKeyDictionary.require("googlebooks");
|
|
4004
|
+
const res = await fetch(
|
|
4005
|
+
`https://www.googleapis.com/books/v1/volumes?q=isbn:${isbn}&key=${key}`
|
|
4006
|
+
);
|
|
4007
|
+
if (!res.ok) return {};
|
|
4008
|
+
const data = await res.json();
|
|
4009
|
+
const info = data.items?.[0]?.volumeInfo ?? {};
|
|
4010
|
+
return {
|
|
4011
|
+
title: info.title,
|
|
4012
|
+
authors: info.authors,
|
|
4013
|
+
publishedDate: info.publishedDate,
|
|
4014
|
+
pageCount: info.pageCount,
|
|
4015
|
+
language: info.language,
|
|
4016
|
+
description: info.description,
|
|
4017
|
+
thumbnail: info.imageLinks?.thumbnail
|
|
4018
|
+
};
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
};
|
|
4023
|
+
|
|
4024
|
+
// src/models/generated-src/Book.ts
|
|
4025
|
+
var schema3 = schemas["Book"];
|
|
4026
|
+
Registry.register(schema3);
|
|
4027
|
+
var BOOK_PROP_IDS = { title: 0, description: 1, originalLang: 2, ageGradeBand: 3, previewTxId: 4, safe: 5, deleted: 6, lifecycleStatus: 7, prerequisites: 8, deweyDecimal: 9, locCallNumber: 10, copyrightStatus: 11, textQuality: 12, illustrations: 13, educationQuality: 14, practicality: 15, accessibilityLevel: 16, teacherMaterials: 17, pedagogicalScaffolding: 18, clarityOfExplanation: 19, workedExamples: 20, exercisesAndAssessment: 21, selfStudyReadiness: 22, referenceApparatus: 23, safetyGuidance: 24, contentCurrency: 25, ecoRegeneration: 26, communityLiving: 27, promotesPeace: 28, businessDevelopment: 29, language: 30, downloadTxId: 31, method: 32, isAiTranslation: 33, aiEngine: 34, addedAt: 35, nbPages: 36, sizeBytes: 37, publisher: 38, publicationDate: 39, publishedAt: 40, qualityScore: 41, isbn: 42 };
|
|
4028
|
+
function serializeBookSlim(records) {
|
|
4029
|
+
return commonSerializeSlim(schema3, records, currentLayout());
|
|
4030
|
+
}
|
|
4031
|
+
function serializeBookExtended(records) {
|
|
4032
|
+
return commonSerializeExtended(schema3, records, currentLayout());
|
|
4033
|
+
}
|
|
4034
|
+
function serializeBookProv(records) {
|
|
4035
|
+
return commonSerializeProv(schema3, records);
|
|
4036
|
+
}
|
|
4037
|
+
var _Book = class _Book extends Orm {
|
|
4038
|
+
constructor(json, creatorUsername) {
|
|
4039
|
+
super(_Book.type, json, creatorUsername);
|
|
4040
|
+
}
|
|
4041
|
+
/** Synchronous LRU read — throws on miss (use LoadAsync to re-hydrate). */
|
|
4042
|
+
static Load(id, creatorUsername) {
|
|
4043
|
+
return getRecord(_Book.type, id, creatorUsername);
|
|
4044
|
+
}
|
|
4045
|
+
static Has(id, creatorUsername) {
|
|
4046
|
+
return hasRecord(_Book.type, id, creatorUsername);
|
|
4047
|
+
}
|
|
4048
|
+
/** On-demand hydration from the worker after LRU eviction (SPEC §2.5). */
|
|
4049
|
+
static async LoadAsync(id, creatorUsername) {
|
|
4050
|
+
if (hasRecord(_Book.type, id, creatorUsername)) {
|
|
4051
|
+
return getRecord(_Book.type, id, creatorUsername);
|
|
4052
|
+
}
|
|
4053
|
+
const thread = PatchInstance.threadInstance;
|
|
4054
|
+
if (!thread) throw new Error("worker thread not initialized \u2014 call PatchInstance.initThread first");
|
|
4055
|
+
const res = await thread.sendRequest({
|
|
4056
|
+
cmd: "getRecord" /* GetRecord */,
|
|
4057
|
+
payload: { objectType: _Book.type, id }
|
|
4058
|
+
});
|
|
4059
|
+
if (!res || res.length === 0) throw new Error(`Book ${id} not found in worker storage`);
|
|
4060
|
+
const record = NewBookWithId(id, creatorUsername);
|
|
4061
|
+
for (const data of res) {
|
|
4062
|
+
if (data.slim) record.mergeSlim(data.slim, 0, data.lang);
|
|
4063
|
+
if (data.extended) record.mergeExtended(data.extended, 0, data.lang);
|
|
4064
|
+
if (data.prov) record.mergeProv(data.prov, 0, data.lang);
|
|
4065
|
+
}
|
|
4066
|
+
return record;
|
|
4067
|
+
}
|
|
4068
|
+
get prerequisites() {
|
|
4069
|
+
return this.getProp(8);
|
|
4070
|
+
}
|
|
4071
|
+
set prerequisites(value) {
|
|
4072
|
+
this.dispatchString(8, value);
|
|
4073
|
+
}
|
|
4074
|
+
getPrerequisites(lang) {
|
|
4075
|
+
return this.getProp(8, lang);
|
|
4076
|
+
}
|
|
4077
|
+
setPrerequisites(value, lang) {
|
|
4078
|
+
this.dispatchString(8, value, lang);
|
|
4079
|
+
}
|
|
4080
|
+
get deweyDecimal() {
|
|
4081
|
+
return this.getProp(9);
|
|
4082
|
+
}
|
|
4083
|
+
set deweyDecimal(value) {
|
|
4084
|
+
this.dispatchString(9, value);
|
|
4085
|
+
}
|
|
4086
|
+
getDeweyDecimal(lang) {
|
|
4087
|
+
return this.getProp(9, lang);
|
|
4088
|
+
}
|
|
4089
|
+
setDeweyDecimal(value, lang) {
|
|
4090
|
+
this.dispatchString(9, value, lang);
|
|
4091
|
+
}
|
|
4092
|
+
get locCallNumber() {
|
|
4093
|
+
return this.getProp(10);
|
|
4094
|
+
}
|
|
4095
|
+
set locCallNumber(value) {
|
|
4096
|
+
this.dispatchString(10, value);
|
|
4097
|
+
}
|
|
4098
|
+
getLocCallNumber(lang) {
|
|
4099
|
+
return this.getProp(10, lang);
|
|
4100
|
+
}
|
|
4101
|
+
setLocCallNumber(value, lang) {
|
|
4102
|
+
this.dispatchString(10, value, lang);
|
|
4103
|
+
}
|
|
4104
|
+
get copyrightStatus() {
|
|
4105
|
+
return this.getProp(11) ?? 0;
|
|
4106
|
+
}
|
|
4107
|
+
set copyrightStatus(value) {
|
|
4108
|
+
this.dispatchNumber(11, value);
|
|
4109
|
+
}
|
|
4110
|
+
getCopyrightStatus(lang) {
|
|
4111
|
+
return this.getProp(11, lang) ?? 0;
|
|
4112
|
+
}
|
|
4113
|
+
setCopyrightStatus(value, lang) {
|
|
4114
|
+
this.dispatchNumber(11, value, lang);
|
|
4115
|
+
}
|
|
4116
|
+
get textQuality() {
|
|
4117
|
+
return this.getProp(12) ?? 0;
|
|
4118
|
+
}
|
|
4119
|
+
set textQuality(value) {
|
|
4120
|
+
this.dispatchNumber(12, value);
|
|
4121
|
+
}
|
|
4122
|
+
getTextQuality(lang) {
|
|
4123
|
+
return this.getProp(12, lang) ?? 0;
|
|
4124
|
+
}
|
|
4125
|
+
setTextQuality(value, lang) {
|
|
4126
|
+
this.dispatchNumber(12, value, lang);
|
|
4127
|
+
}
|
|
4128
|
+
get illustrations() {
|
|
4129
|
+
return this.getProp(13) ?? 0;
|
|
4130
|
+
}
|
|
4131
|
+
set illustrations(value) {
|
|
4132
|
+
this.dispatchNumber(13, value);
|
|
4133
|
+
}
|
|
4134
|
+
getIllustrations(lang) {
|
|
4135
|
+
return this.getProp(13, lang) ?? 0;
|
|
4136
|
+
}
|
|
4137
|
+
setIllustrations(value, lang) {
|
|
4138
|
+
this.dispatchNumber(13, value, lang);
|
|
4139
|
+
}
|
|
4140
|
+
get educationQuality() {
|
|
4141
|
+
return this.getProp(14) ?? 0;
|
|
4142
|
+
}
|
|
4143
|
+
set educationQuality(value) {
|
|
4144
|
+
this.dispatchNumber(14, value);
|
|
4145
|
+
}
|
|
4146
|
+
getEducationQuality(lang) {
|
|
4147
|
+
return this.getProp(14, lang) ?? 0;
|
|
4148
|
+
}
|
|
4149
|
+
setEducationQuality(value, lang) {
|
|
4150
|
+
this.dispatchNumber(14, value, lang);
|
|
4151
|
+
}
|
|
4152
|
+
get practicality() {
|
|
4153
|
+
return this.getProp(15) ?? 0;
|
|
4154
|
+
}
|
|
4155
|
+
set practicality(value) {
|
|
4156
|
+
this.dispatchNumber(15, value);
|
|
4157
|
+
}
|
|
4158
|
+
getPracticality(lang) {
|
|
4159
|
+
return this.getProp(15, lang) ?? 0;
|
|
4160
|
+
}
|
|
4161
|
+
setPracticality(value, lang) {
|
|
4162
|
+
this.dispatchNumber(15, value, lang);
|
|
4163
|
+
}
|
|
4164
|
+
get accessibilityLevel() {
|
|
4165
|
+
return this.getProp(16) ?? 0;
|
|
4166
|
+
}
|
|
4167
|
+
set accessibilityLevel(value) {
|
|
4168
|
+
this.dispatchNumber(16, value);
|
|
4169
|
+
}
|
|
4170
|
+
getAccessibilityLevel(lang) {
|
|
4171
|
+
return this.getProp(16, lang) ?? 0;
|
|
4172
|
+
}
|
|
4173
|
+
setAccessibilityLevel(value, lang) {
|
|
4174
|
+
this.dispatchNumber(16, value, lang);
|
|
4175
|
+
}
|
|
4176
|
+
get teacherMaterials() {
|
|
4177
|
+
return this.getProp(17) ?? false;
|
|
4178
|
+
}
|
|
4179
|
+
set teacherMaterials(value) {
|
|
4180
|
+
this.dispatchNumber(17, value ? 1 : 0);
|
|
4181
|
+
}
|
|
4182
|
+
getTeacherMaterials(lang) {
|
|
4183
|
+
return this.getProp(17, lang) ?? false;
|
|
4184
|
+
}
|
|
4185
|
+
setTeacherMaterials(value, lang) {
|
|
4186
|
+
this.dispatchNumber(17, value ? 1 : 0, lang);
|
|
4187
|
+
}
|
|
4188
|
+
get pedagogicalScaffolding() {
|
|
4189
|
+
return this.getProp(18) ?? 0;
|
|
4190
|
+
}
|
|
4191
|
+
set pedagogicalScaffolding(value) {
|
|
4192
|
+
this.dispatchNumber(18, value);
|
|
4193
|
+
}
|
|
4194
|
+
getPedagogicalScaffolding(lang) {
|
|
4195
|
+
return this.getProp(18, lang) ?? 0;
|
|
4196
|
+
}
|
|
4197
|
+
setPedagogicalScaffolding(value, lang) {
|
|
4198
|
+
this.dispatchNumber(18, value, lang);
|
|
4199
|
+
}
|
|
4200
|
+
get clarityOfExplanation() {
|
|
4201
|
+
return this.getProp(19) ?? 0;
|
|
4202
|
+
}
|
|
4203
|
+
set clarityOfExplanation(value) {
|
|
4204
|
+
this.dispatchNumber(19, value);
|
|
4205
|
+
}
|
|
4206
|
+
getClarityOfExplanation(lang) {
|
|
4207
|
+
return this.getProp(19, lang) ?? 0;
|
|
4208
|
+
}
|
|
4209
|
+
setClarityOfExplanation(value, lang) {
|
|
4210
|
+
this.dispatchNumber(19, value, lang);
|
|
4211
|
+
}
|
|
4212
|
+
get workedExamples() {
|
|
4213
|
+
return this.getProp(20) ?? 0;
|
|
4214
|
+
}
|
|
4215
|
+
set workedExamples(value) {
|
|
4216
|
+
this.dispatchNumber(20, value);
|
|
4217
|
+
}
|
|
4218
|
+
getWorkedExamples(lang) {
|
|
4219
|
+
return this.getProp(20, lang) ?? 0;
|
|
4220
|
+
}
|
|
4221
|
+
setWorkedExamples(value, lang) {
|
|
4222
|
+
this.dispatchNumber(20, value, lang);
|
|
4223
|
+
}
|
|
4224
|
+
get exercisesAndAssessment() {
|
|
4225
|
+
return this.getProp(21) ?? 0;
|
|
4226
|
+
}
|
|
4227
|
+
set exercisesAndAssessment(value) {
|
|
4228
|
+
this.dispatchNumber(21, value);
|
|
4229
|
+
}
|
|
4230
|
+
getExercisesAndAssessment(lang) {
|
|
4231
|
+
return this.getProp(21, lang) ?? 0;
|
|
4232
|
+
}
|
|
4233
|
+
setExercisesAndAssessment(value, lang) {
|
|
4234
|
+
this.dispatchNumber(21, value, lang);
|
|
4235
|
+
}
|
|
4236
|
+
get selfStudyReadiness() {
|
|
4237
|
+
return this.getProp(22) ?? 0;
|
|
4238
|
+
}
|
|
4239
|
+
set selfStudyReadiness(value) {
|
|
4240
|
+
this.dispatchNumber(22, value);
|
|
4241
|
+
}
|
|
4242
|
+
getSelfStudyReadiness(lang) {
|
|
4243
|
+
return this.getProp(22, lang) ?? 0;
|
|
4244
|
+
}
|
|
4245
|
+
setSelfStudyReadiness(value, lang) {
|
|
4246
|
+
this.dispatchNumber(22, value, lang);
|
|
4247
|
+
}
|
|
4248
|
+
get referenceApparatus() {
|
|
4249
|
+
return this.getProp(23) ?? 0;
|
|
4250
|
+
}
|
|
4251
|
+
set referenceApparatus(value) {
|
|
4252
|
+
this.dispatchNumber(23, value);
|
|
4253
|
+
}
|
|
4254
|
+
getReferenceApparatus(lang) {
|
|
4255
|
+
return this.getProp(23, lang) ?? 0;
|
|
4256
|
+
}
|
|
4257
|
+
setReferenceApparatus(value, lang) {
|
|
4258
|
+
this.dispatchNumber(23, value, lang);
|
|
4259
|
+
}
|
|
4260
|
+
get safetyGuidance() {
|
|
4261
|
+
return this.getProp(24) ?? 0;
|
|
4262
|
+
}
|
|
4263
|
+
set safetyGuidance(value) {
|
|
4264
|
+
this.dispatchNumber(24, value);
|
|
4265
|
+
}
|
|
4266
|
+
getSafetyGuidance(lang) {
|
|
4267
|
+
return this.getProp(24, lang) ?? 0;
|
|
4268
|
+
}
|
|
4269
|
+
setSafetyGuidance(value, lang) {
|
|
4270
|
+
this.dispatchNumber(24, value, lang);
|
|
4271
|
+
}
|
|
4272
|
+
get contentCurrency() {
|
|
4273
|
+
return this.getProp(25) ?? 0;
|
|
4274
|
+
}
|
|
4275
|
+
set contentCurrency(value) {
|
|
4276
|
+
this.dispatchNumber(25, value);
|
|
4277
|
+
}
|
|
4278
|
+
getContentCurrency(lang) {
|
|
4279
|
+
return this.getProp(25, lang) ?? 0;
|
|
4280
|
+
}
|
|
4281
|
+
setContentCurrency(value, lang) {
|
|
4282
|
+
this.dispatchNumber(25, value, lang);
|
|
4283
|
+
}
|
|
4284
|
+
get ecoRegeneration() {
|
|
4285
|
+
return this.getProp(26) ?? 0;
|
|
4286
|
+
}
|
|
4287
|
+
set ecoRegeneration(value) {
|
|
4288
|
+
this.dispatchNumber(26, value);
|
|
4289
|
+
}
|
|
4290
|
+
getEcoRegeneration(lang) {
|
|
4291
|
+
return this.getProp(26, lang) ?? 0;
|
|
4292
|
+
}
|
|
4293
|
+
setEcoRegeneration(value, lang) {
|
|
4294
|
+
this.dispatchNumber(26, value, lang);
|
|
4295
|
+
}
|
|
4296
|
+
get communityLiving() {
|
|
4297
|
+
return this.getProp(27) ?? 0;
|
|
4298
|
+
}
|
|
4299
|
+
set communityLiving(value) {
|
|
4300
|
+
this.dispatchNumber(27, value);
|
|
4301
|
+
}
|
|
4302
|
+
getCommunityLiving(lang) {
|
|
4303
|
+
return this.getProp(27, lang) ?? 0;
|
|
4304
|
+
}
|
|
4305
|
+
setCommunityLiving(value, lang) {
|
|
4306
|
+
this.dispatchNumber(27, value, lang);
|
|
4307
|
+
}
|
|
4308
|
+
get promotesPeace() {
|
|
4309
|
+
return this.getProp(28) ?? 0;
|
|
4310
|
+
}
|
|
4311
|
+
set promotesPeace(value) {
|
|
4312
|
+
this.dispatchNumber(28, value);
|
|
4313
|
+
}
|
|
4314
|
+
getPromotesPeace(lang) {
|
|
4315
|
+
return this.getProp(28, lang) ?? 0;
|
|
4316
|
+
}
|
|
4317
|
+
setPromotesPeace(value, lang) {
|
|
4318
|
+
this.dispatchNumber(28, value, lang);
|
|
4319
|
+
}
|
|
4320
|
+
get businessDevelopment() {
|
|
4321
|
+
return this.getProp(29) ?? 0;
|
|
4322
|
+
}
|
|
4323
|
+
set businessDevelopment(value) {
|
|
4324
|
+
this.dispatchNumber(29, value);
|
|
4325
|
+
}
|
|
4326
|
+
getBusinessDevelopment(lang) {
|
|
4327
|
+
return this.getProp(29, lang) ?? 0;
|
|
4328
|
+
}
|
|
4329
|
+
setBusinessDevelopment(value, lang) {
|
|
4330
|
+
this.dispatchNumber(29, value, lang);
|
|
4331
|
+
}
|
|
4332
|
+
get inTagsIds() {
|
|
4333
|
+
return Array.from(this._in.get(0).values());
|
|
4334
|
+
}
|
|
4335
|
+
get inTags() {
|
|
4336
|
+
return this.inTagsIds.map((id) => Tag.Load(id));
|
|
4337
|
+
}
|
|
4338
|
+
isInTag(id) {
|
|
4339
|
+
return this._in.get(0).has(id);
|
|
4340
|
+
}
|
|
4341
|
+
addIntoTag(id) {
|
|
4342
|
+
if (this.isInTag(id)) return;
|
|
4343
|
+
const op = {
|
|
4344
|
+
operation: PatchOperation.EditRelation,
|
|
4345
|
+
objectType: Tag.type,
|
|
4346
|
+
objectId: id,
|
|
4347
|
+
langId: 0,
|
|
4348
|
+
relationId: 4,
|
|
4349
|
+
// canonical: Tag.books
|
|
4350
|
+
action: PatchAction.Add,
|
|
4351
|
+
targetId: this.id
|
|
4352
|
+
};
|
|
4353
|
+
if (hasRecord(Tag.type, id)) {
|
|
4354
|
+
getRecord(Tag.type, id).patch(op);
|
|
4355
|
+
}
|
|
4356
|
+
this.applyRelationRaw("in", 0, PatchAction.Add, id);
|
|
4357
|
+
PatchInstance.addPatch(op);
|
|
4358
|
+
}
|
|
4359
|
+
removeFromTag(id) {
|
|
4360
|
+
if (!this.isInTag(id)) return;
|
|
4361
|
+
const op = {
|
|
4362
|
+
operation: PatchOperation.EditRelation,
|
|
4363
|
+
objectType: Tag.type,
|
|
4364
|
+
objectId: id,
|
|
4365
|
+
langId: 0,
|
|
4366
|
+
relationId: 4,
|
|
4367
|
+
// canonical: Tag.books
|
|
4368
|
+
action: PatchAction.Remove,
|
|
4369
|
+
targetId: this.id
|
|
4370
|
+
};
|
|
4371
|
+
if (hasRecord(Tag.type, id)) {
|
|
4372
|
+
getRecord(Tag.type, id).patch(op);
|
|
4373
|
+
}
|
|
4374
|
+
this.applyRelationRaw("in", 0, PatchAction.Remove, id);
|
|
4375
|
+
PatchInstance.addPatch(op);
|
|
4376
|
+
}
|
|
4377
|
+
get authorsIds() {
|
|
4378
|
+
return Array.from(this._has.get(1).values());
|
|
4379
|
+
}
|
|
4380
|
+
get authors() {
|
|
4381
|
+
return this.authorsIds.map((id) => Person.Load(id));
|
|
4382
|
+
}
|
|
4383
|
+
hasAuthor(id) {
|
|
4384
|
+
return this._has.get(1).has(id);
|
|
4385
|
+
}
|
|
4386
|
+
addAuthor(id) {
|
|
4387
|
+
if (this.hasAuthor(id)) return;
|
|
4388
|
+
this.dispatchRelation(1, PatchAction.Add, id);
|
|
4389
|
+
}
|
|
4390
|
+
removeAuthor(id) {
|
|
4391
|
+
if (!this.hasAuthor(id)) return;
|
|
4392
|
+
this.dispatchRelation(1, PatchAction.Remove, id);
|
|
4393
|
+
}
|
|
4394
|
+
getInstances(lang = Config.userLang) {
|
|
4395
|
+
return this.getInstancesData(lang).map((data, i) => new BookInstance(this, lang, i, data));
|
|
4396
|
+
}
|
|
4397
|
+
getInstance(index, lang = Config.userLang) {
|
|
4398
|
+
return this.getInstances(lang)[index];
|
|
4399
|
+
}
|
|
4400
|
+
getDefaultInstance(lang = Config.userLang) {
|
|
4401
|
+
const instances = this.getInstances(lang);
|
|
4402
|
+
return instances.find((i) => i.isDefault) ?? instances[0];
|
|
4403
|
+
}
|
|
4404
|
+
// ── UID methods ─────────────────────────────────────────────────────────
|
|
4405
|
+
toPID() {
|
|
4406
|
+
const scope = this.id & 2147483648 ? "U" : "C";
|
|
4407
|
+
return `DL:${scope}:BK:${encodePID("BK", this.id)}`;
|
|
4408
|
+
}
|
|
4409
|
+
toNativePID() {
|
|
4410
|
+
return this.toPID();
|
|
4411
|
+
}
|
|
4412
|
+
static fromPID(pid) {
|
|
4413
|
+
try {
|
|
4414
|
+
if (!pid.startsWith("DL:")) return decodePID("BK", pid);
|
|
4415
|
+
const parts = pid.split(":");
|
|
4416
|
+
if (parts.length >= 4 && parts[2] === "BK") {
|
|
4417
|
+
return decodePID("BK", parts[3]);
|
|
4418
|
+
}
|
|
4419
|
+
return null;
|
|
4420
|
+
} catch {
|
|
4421
|
+
return null;
|
|
4422
|
+
}
|
|
4423
|
+
}
|
|
4424
|
+
// Merge methods are now implemented in Orm using the schema definition.
|
|
4425
|
+
static async LoadInstance(pkValue, lang) {
|
|
4426
|
+
const crosswalk = globalThis.ExternalIdCrosswalk?.instance;
|
|
4427
|
+
if (!crosswalk) throw new Error("ExternalIdCrosswalk not initialized \u2014 bootup incomplete");
|
|
4428
|
+
await crosswalk.whenReady();
|
|
4429
|
+
if (pkValue.startsWith("DL:C:DERIVED:")) {
|
|
4430
|
+
const result2 = await crosswalk.resolveDerived(pkValue, lang);
|
|
4431
|
+
if (!result2) return null;
|
|
4432
|
+
const record2 = await _Book.LoadAsync(result2.wireId);
|
|
4433
|
+
return record2 ? { record: record2, instanceIndex: result2.instanceIndex } : null;
|
|
4434
|
+
}
|
|
4435
|
+
if (pkValue.startsWith("DL:C:")) {
|
|
4436
|
+
const parsed = _Book.fromPID(pkValue);
|
|
4437
|
+
if (parsed) {
|
|
4438
|
+
const record2 = await _Book.LoadAsync(parsed.wireId);
|
|
4439
|
+
return record2 ? { record: record2 } : null;
|
|
4440
|
+
}
|
|
4441
|
+
return null;
|
|
4442
|
+
}
|
|
4443
|
+
const colon = pkValue.indexOf(":");
|
|
4444
|
+
if (colon === -1) return null;
|
|
4445
|
+
const standardId = pkValue.slice(0, colon);
|
|
4446
|
+
const value = pkValue.slice(colon + 1);
|
|
4447
|
+
const result = await crosswalk.resolveForInstance(standardId, value, lang);
|
|
4448
|
+
if (!result) return null;
|
|
4449
|
+
const record = await _Book.LoadAsync(result.wireId);
|
|
4450
|
+
return record ? { record, instanceIndex: result.instanceIndex } : null;
|
|
4451
|
+
}
|
|
4452
|
+
};
|
|
4453
|
+
_Book.type = 0;
|
|
4454
|
+
_Book.UID_STRATEGY = "native-only";
|
|
4455
|
+
_Book.STANDARD_PRIORITY = [];
|
|
4456
|
+
_Book.serializeSlim = serializeBookSlim;
|
|
4457
|
+
_Book.serializeExtended = serializeBookExtended;
|
|
4458
|
+
_Book.serializeProv = serializeBookProv;
|
|
4459
|
+
var Book = _Book;
|
|
4460
|
+
var BookInstance = class {
|
|
4461
|
+
constructor(parent, lang, index, data) {
|
|
4462
|
+
this.parent = parent;
|
|
4463
|
+
this.lang = lang;
|
|
4464
|
+
this.index = index;
|
|
4465
|
+
this.data = data;
|
|
4466
|
+
}
|
|
4467
|
+
get isDefault() {
|
|
4468
|
+
return this.data["isDefault"] === true;
|
|
4469
|
+
}
|
|
4470
|
+
get language() {
|
|
4471
|
+
return this.data["language"] ?? "";
|
|
4472
|
+
}
|
|
4473
|
+
set language(val) {
|
|
4474
|
+
this.data["language"] = val;
|
|
4475
|
+
const op = {
|
|
4476
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4477
|
+
objectType: Book.type,
|
|
4478
|
+
objectId: this.parent.id,
|
|
4479
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4480
|
+
instanceIndex: this.index,
|
|
4481
|
+
propertyId: 30,
|
|
4482
|
+
// language — instanceField global propId
|
|
4483
|
+
value: val ?? ""
|
|
4484
|
+
};
|
|
4485
|
+
this.parent.patch(op);
|
|
4486
|
+
PatchInstance.addPatch(op);
|
|
4487
|
+
}
|
|
4488
|
+
get downloadTxId() {
|
|
4489
|
+
return this.data["downloadTxId"] ?? "";
|
|
4490
|
+
}
|
|
4491
|
+
set downloadTxId(val) {
|
|
4492
|
+
this.data["downloadTxId"] = val;
|
|
4493
|
+
const op = {
|
|
4494
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4495
|
+
objectType: Book.type,
|
|
4496
|
+
objectId: this.parent.id,
|
|
4497
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4498
|
+
instanceIndex: this.index,
|
|
4499
|
+
propertyId: 31,
|
|
4500
|
+
// downloadTxId — instanceField global propId
|
|
4501
|
+
value: val ?? ""
|
|
4502
|
+
};
|
|
4503
|
+
this.parent.patch(op);
|
|
4504
|
+
PatchInstance.addPatch(op);
|
|
4505
|
+
}
|
|
4506
|
+
get method() {
|
|
4507
|
+
return this.data["method"] ?? 0;
|
|
4508
|
+
}
|
|
4509
|
+
set method(val) {
|
|
4510
|
+
this.data["method"] = val;
|
|
4511
|
+
const op = {
|
|
4512
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4513
|
+
objectType: Book.type,
|
|
4514
|
+
objectId: this.parent.id,
|
|
4515
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4516
|
+
instanceIndex: this.index,
|
|
4517
|
+
propertyId: 32,
|
|
4518
|
+
// method — instanceField global propId
|
|
4519
|
+
value: val
|
|
4520
|
+
};
|
|
4521
|
+
this.parent.patch(op);
|
|
4522
|
+
PatchInstance.addPatch(op);
|
|
4523
|
+
}
|
|
4524
|
+
get isAiTranslation() {
|
|
4525
|
+
return this.data["isAiTranslation"] ?? false;
|
|
4526
|
+
}
|
|
4527
|
+
set isAiTranslation(val) {
|
|
4528
|
+
this.data["isAiTranslation"] = val;
|
|
4529
|
+
const op = {
|
|
4530
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4531
|
+
objectType: Book.type,
|
|
4532
|
+
objectId: this.parent.id,
|
|
4533
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4534
|
+
instanceIndex: this.index,
|
|
4535
|
+
propertyId: 33,
|
|
4536
|
+
// isAiTranslation — instanceField global propId
|
|
4537
|
+
value: val ? 1 : 0
|
|
4538
|
+
};
|
|
4539
|
+
this.parent.patch(op);
|
|
4540
|
+
PatchInstance.addPatch(op);
|
|
4541
|
+
}
|
|
4542
|
+
get aiEngine() {
|
|
4543
|
+
return this.data["aiEngine"] ?? null;
|
|
4544
|
+
}
|
|
4545
|
+
set aiEngine(val) {
|
|
4546
|
+
this.data["aiEngine"] = val;
|
|
4547
|
+
const op = {
|
|
4548
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4549
|
+
objectType: Book.type,
|
|
4550
|
+
objectId: this.parent.id,
|
|
4551
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4552
|
+
instanceIndex: this.index,
|
|
4553
|
+
propertyId: 34,
|
|
4554
|
+
// aiEngine — instanceField global propId
|
|
4555
|
+
value: val ?? ""
|
|
4556
|
+
};
|
|
4557
|
+
this.parent.patch(op);
|
|
4558
|
+
PatchInstance.addPatch(op);
|
|
4559
|
+
}
|
|
4560
|
+
get addedAt() {
|
|
4561
|
+
return this.data["addedAt"] ?? 0;
|
|
4562
|
+
}
|
|
4563
|
+
set addedAt(val) {
|
|
4564
|
+
this.data["addedAt"] = val;
|
|
4565
|
+
const op = {
|
|
4566
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4567
|
+
objectType: Book.type,
|
|
4568
|
+
objectId: this.parent.id,
|
|
4569
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4570
|
+
instanceIndex: this.index,
|
|
4571
|
+
propertyId: 35,
|
|
4572
|
+
// addedAt — instanceField global propId
|
|
4573
|
+
value: val
|
|
4574
|
+
};
|
|
4575
|
+
this.parent.patch(op);
|
|
4576
|
+
PatchInstance.addPatch(op);
|
|
4577
|
+
}
|
|
4578
|
+
get nbPages() {
|
|
4579
|
+
return this.data["nbPages"] ?? 0;
|
|
4580
|
+
}
|
|
4581
|
+
set nbPages(val) {
|
|
4582
|
+
this.data["nbPages"] = val;
|
|
4583
|
+
const op = {
|
|
4584
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4585
|
+
objectType: Book.type,
|
|
4586
|
+
objectId: this.parent.id,
|
|
4587
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4588
|
+
instanceIndex: this.index,
|
|
4589
|
+
propertyId: 36,
|
|
4590
|
+
// nbPages — instanceField global propId
|
|
4591
|
+
value: val
|
|
4592
|
+
};
|
|
4593
|
+
this.parent.patch(op);
|
|
4594
|
+
PatchInstance.addPatch(op);
|
|
4595
|
+
}
|
|
4596
|
+
get sizeBytes() {
|
|
4597
|
+
return this.data["sizeBytes"] ?? 0;
|
|
4598
|
+
}
|
|
4599
|
+
set sizeBytes(val) {
|
|
4600
|
+
this.data["sizeBytes"] = val;
|
|
4601
|
+
const op = {
|
|
4602
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4603
|
+
objectType: Book.type,
|
|
4604
|
+
objectId: this.parent.id,
|
|
4605
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4606
|
+
instanceIndex: this.index,
|
|
4607
|
+
propertyId: 37,
|
|
4608
|
+
// sizeBytes — instanceField global propId
|
|
4609
|
+
value: val
|
|
4610
|
+
};
|
|
4611
|
+
this.parent.patch(op);
|
|
4612
|
+
PatchInstance.addPatch(op);
|
|
4613
|
+
}
|
|
4614
|
+
get publisher() {
|
|
4615
|
+
return this.data["publisher"] ?? null;
|
|
4616
|
+
}
|
|
4617
|
+
set publisher(val) {
|
|
4618
|
+
this.data["publisher"] = val;
|
|
4619
|
+
const op = {
|
|
4620
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4621
|
+
objectType: Book.type,
|
|
4622
|
+
objectId: this.parent.id,
|
|
4623
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4624
|
+
instanceIndex: this.index,
|
|
4625
|
+
propertyId: 38,
|
|
4626
|
+
// publisher — instanceField global propId
|
|
4627
|
+
value: val ?? ""
|
|
4628
|
+
};
|
|
4629
|
+
this.parent.patch(op);
|
|
4630
|
+
PatchInstance.addPatch(op);
|
|
4631
|
+
}
|
|
4632
|
+
get publicationDate() {
|
|
4633
|
+
return this.data["publicationDate"] ?? null;
|
|
4634
|
+
}
|
|
4635
|
+
set publicationDate(val) {
|
|
4636
|
+
this.data["publicationDate"] = val;
|
|
4637
|
+
const op = {
|
|
4638
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4639
|
+
objectType: Book.type,
|
|
4640
|
+
objectId: this.parent.id,
|
|
4641
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4642
|
+
instanceIndex: this.index,
|
|
4643
|
+
propertyId: 39,
|
|
4644
|
+
// publicationDate — instanceField global propId
|
|
4645
|
+
value: val ?? ""
|
|
4646
|
+
};
|
|
4647
|
+
this.parent.patch(op);
|
|
4648
|
+
PatchInstance.addPatch(op);
|
|
4649
|
+
}
|
|
4650
|
+
get publishedAt() {
|
|
4651
|
+
return this.data["publishedAt"] ?? null;
|
|
4652
|
+
}
|
|
4653
|
+
set publishedAt(val) {
|
|
4654
|
+
this.data["publishedAt"] = val;
|
|
4655
|
+
const op = {
|
|
4656
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4657
|
+
objectType: Book.type,
|
|
4658
|
+
objectId: this.parent.id,
|
|
4659
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4660
|
+
instanceIndex: this.index,
|
|
4661
|
+
propertyId: 40,
|
|
4662
|
+
// publishedAt — instanceField global propId
|
|
4663
|
+
value: val ?? ""
|
|
4664
|
+
};
|
|
4665
|
+
this.parent.patch(op);
|
|
4666
|
+
PatchInstance.addPatch(op);
|
|
4667
|
+
}
|
|
4668
|
+
get qualityScore() {
|
|
4669
|
+
return this.data["qualityScore"] ?? 0;
|
|
4670
|
+
}
|
|
4671
|
+
set qualityScore(val) {
|
|
4672
|
+
this.data["qualityScore"] = val;
|
|
4673
|
+
const op = {
|
|
4674
|
+
operation: PatchOperation.EditInstanceFieldNumber,
|
|
4675
|
+
objectType: Book.type,
|
|
4676
|
+
objectId: this.parent.id,
|
|
4677
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4678
|
+
instanceIndex: this.index,
|
|
4679
|
+
propertyId: 41,
|
|
4680
|
+
// qualityScore — instanceField global propId
|
|
4681
|
+
value: val
|
|
4682
|
+
};
|
|
4683
|
+
this.parent.patch(op);
|
|
4684
|
+
PatchInstance.addPatch(op);
|
|
4685
|
+
}
|
|
4686
|
+
get isbn() {
|
|
4687
|
+
return this.data["isbn"] ?? null;
|
|
4688
|
+
}
|
|
4689
|
+
set isbn(val) {
|
|
4690
|
+
this.data["isbn"] = val;
|
|
4691
|
+
const op = {
|
|
4692
|
+
operation: PatchOperation.EditInstanceFieldString,
|
|
4693
|
+
objectType: Book.type,
|
|
4694
|
+
objectId: this.parent.id,
|
|
4695
|
+
langId: LANG_ID_ENCODE[this.lang] ?? 0,
|
|
4696
|
+
instanceIndex: this.index,
|
|
4697
|
+
propertyId: 42,
|
|
4698
|
+
// isbn — instanceField global propId
|
|
4699
|
+
value: val ?? ""
|
|
4700
|
+
};
|
|
4701
|
+
this.parent.patch(op);
|
|
4702
|
+
PatchInstance.addPatch(op);
|
|
4703
|
+
}
|
|
4704
|
+
derivedSfcuid(sourceSfcuid) {
|
|
4705
|
+
const parts = [
|
|
4706
|
+
this.language ?? ""
|
|
4707
|
+
];
|
|
4708
|
+
return `DL:C:DERIVED:${sourceSfcuid}:${parts.map((p) => encodeURIComponent(String(p))).join(":")}`;
|
|
4709
|
+
}
|
|
4710
|
+
// ── Inherited from isbn standard ───────────────────────────────────────
|
|
4711
|
+
get isbnNormalized() {
|
|
4712
|
+
return this.isbn ? ISBNAdapter.normalize(this.isbn) : null;
|
|
4713
|
+
}
|
|
4714
|
+
validateIsbn() {
|
|
4715
|
+
return ISBNAdapter.validate(this.isbn);
|
|
4716
|
+
}
|
|
4717
|
+
sfcuid() {
|
|
4718
|
+
if (this.isbn) return `isbn:${ISBNAdapter.normalize(this.isbn)}`;
|
|
4719
|
+
return this.derivedSfcuid(this.parent.toPID());
|
|
4720
|
+
}
|
|
4721
|
+
get identityCluster() {
|
|
4722
|
+
const primary = this.sfcuid();
|
|
4723
|
+
const allAliases = [
|
|
4724
|
+
this.isbn ? `isbn:${ISBNAdapter.normalize(this.isbn)}` : null,
|
|
4725
|
+
this.parent.toPID()
|
|
4726
|
+
].filter(Boolean);
|
|
4727
|
+
return {
|
|
4728
|
+
sfcuid: primary,
|
|
4729
|
+
native: this.parent.toPID(),
|
|
4730
|
+
aliases: allAliases.filter((a) => a !== primary),
|
|
4731
|
+
wireId: this.parent.id
|
|
4732
|
+
};
|
|
4733
|
+
}
|
|
4734
|
+
// High-ease parent delegates
|
|
4735
|
+
get description() {
|
|
4736
|
+
return this.parent.getDescription(this.lang) ?? "";
|
|
4737
|
+
}
|
|
4738
|
+
set description(val) {
|
|
4739
|
+
this.parent.setDescription(val, this.lang);
|
|
4740
|
+
}
|
|
4741
|
+
};
|
|
4742
|
+
var NewBookWithId = (id, creatorUsername) => {
|
|
4743
|
+
if (hasRecord(Book.type, id, creatorUsername)) {
|
|
4744
|
+
return getRecord(Book.type, id, creatorUsername);
|
|
4745
|
+
}
|
|
4746
|
+
const record = new Book(Book.createNewRequest(id), creatorUsername);
|
|
4747
|
+
addRecord(Book.type, record, creatorUsername);
|
|
4748
|
+
return record;
|
|
4749
|
+
};
|
|
4750
|
+
|
|
4751
|
+
// src/models/generated-src/index.ts
|
|
4752
|
+
var ModelTypes = {
|
|
4753
|
+
[0]: Book,
|
|
4754
|
+
[1]: Person,
|
|
4755
|
+
[2]: Tag
|
|
4756
|
+
};
|
|
4757
|
+
|
|
4758
|
+
export {
|
|
4759
|
+
PatchOperation,
|
|
4760
|
+
PatchAction,
|
|
4761
|
+
LANG_ID_ENCODE,
|
|
4762
|
+
LANG_ID_DECODE,
|
|
4763
|
+
resolveLayout,
|
|
4764
|
+
packPatch,
|
|
4765
|
+
unpackPatch,
|
|
4766
|
+
patchToEvm,
|
|
4767
|
+
evmToPatch,
|
|
4768
|
+
LANG_AGNOSTIC,
|
|
4769
|
+
isEvmPatch,
|
|
4770
|
+
inceptionDate,
|
|
4771
|
+
DateUtils,
|
|
4772
|
+
ActionTypes,
|
|
4773
|
+
WorkerCommands,
|
|
4774
|
+
Rating,
|
|
4775
|
+
WorkerEvent,
|
|
4776
|
+
DownloadState,
|
|
4777
|
+
SidecarType,
|
|
4778
|
+
versionsFile,
|
|
4779
|
+
CURRENT_VERSION,
|
|
4780
|
+
currentLayout,
|
|
4781
|
+
debouncePromise,
|
|
4782
|
+
Patches,
|
|
4783
|
+
PatchInstance,
|
|
4784
|
+
deserializePatches,
|
|
4785
|
+
serializePatches,
|
|
4786
|
+
getPatchInstanceByAccount,
|
|
4787
|
+
PopulateStatsStore,
|
|
4788
|
+
DownloadsByType,
|
|
4789
|
+
VisitsByType,
|
|
4790
|
+
FavoritesByTypes,
|
|
4791
|
+
Stats,
|
|
4792
|
+
addReactivitySystem,
|
|
4793
|
+
setReactivitySystem,
|
|
4794
|
+
dbReactivity,
|
|
4795
|
+
LruCache,
|
|
4796
|
+
configureDb,
|
|
4797
|
+
clear,
|
|
4798
|
+
dump,
|
|
4799
|
+
getRecordKey,
|
|
4800
|
+
hasRecord,
|
|
4801
|
+
getRecord,
|
|
4802
|
+
addRecord,
|
|
4803
|
+
removeRecord,
|
|
4804
|
+
pinRecord,
|
|
4805
|
+
unpinRecord,
|
|
4806
|
+
localRecordTable,
|
|
4807
|
+
extractRecordCols,
|
|
4808
|
+
relationColName2 as relationColName,
|
|
4809
|
+
SchemaRegistry,
|
|
4810
|
+
Registry,
|
|
4811
|
+
Config,
|
|
4812
|
+
setDefaultLanguage,
|
|
4813
|
+
Orm,
|
|
4814
|
+
PERSON_PROP_IDS,
|
|
4815
|
+
serializePersonSlim,
|
|
4816
|
+
serializePersonExtended,
|
|
4817
|
+
serializePersonProv,
|
|
4818
|
+
Person,
|
|
4819
|
+
NewPersonWithId,
|
|
4820
|
+
TAG_PROP_IDS,
|
|
4821
|
+
serializeTagSlim,
|
|
4822
|
+
serializeTagExtended,
|
|
4823
|
+
serializeTagProv,
|
|
4824
|
+
Tag,
|
|
4825
|
+
NewTagWithId,
|
|
4826
|
+
BOOK_PROP_IDS,
|
|
4827
|
+
serializeBookSlim,
|
|
4828
|
+
serializeBookExtended,
|
|
4829
|
+
serializeBookProv,
|
|
4830
|
+
Book,
|
|
4831
|
+
BookInstance,
|
|
4832
|
+
NewBookWithId,
|
|
4833
|
+
ModelTypes
|
|
4834
|
+
};
|
|
4835
|
+
//# sourceMappingURL=chunk-JDUYLUDJ.js.map
|