๐ src/models/generated-src/Person.ts
D-OPEN SOVEREIGN
Documentation & Insights
propName -> propId (provenance column mapping)Synchronous LRU read โ throws on miss (use LoadAsync to re-hydrate).On-demand hydration from the worker after LRU eviction (SPEC ยง2.5).1// AUTO-GENERATED by @the_library/db_schemas schemaGenerator โ run `pnpm generate` to rebuild.
2import { Orm, Config } from "../orm.ts";
3import { Registry, type ModelDefinition } from "../registry.ts";
4import { PatchOperation, PatchAction, LANG_ID_ENCODE, type EditInstanceFieldNumberObj, type EditInstanceFieldStringObj, type EditRelationObj } from "../binary.ts";
5import { PatchInstance } from "../patcher.ts";
6import { addRecord, getRecord, hasRecord } from "../db.ts";
7import type { uid, Lang, CommonOrmJson, SerializedCommonOrmJson, InstanceData, RecordIdentityCluster } from "../interfaces.ts";
8import { WorkerCommands, SidecarType } from "../enums.ts";
9import { ColumnType, type SidecarInput, type SidecarRelationInput, instanceSpecFromFields } from "../enriched-index.ts";
10import { encodePID, decodePID } from "../pid.ts";
11import { schemas } from "@the_library/db_schemas/schemas";
12import { commonSerializeSlim, commonSerializeExtended, commonSerializeProv } from "../serializer.ts";
13import { currentLayout } from "../versions.ts";
14import { Book } from "./Book.ts";
15import { ISNIAdapter } from "@the_library/standard-adapters/isni";
16import { ORCIDAdapter } from "@the_library/standard-adapters/orcid";
17
18const schema = schemas["Person"] as ModelDefinition;
19
20Registry.register(schema);
21
22/** propName -> propId (provenance column mapping) */
23export const PERSON_PROP_IDS: Record<string, number> = { 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 };
24
25export interface PersonSlimCols {
26 ids: Uint16Array;
27 titles: (string | null)[];
28 originalLangs: (string | null)[];
29 previewTxIds: (string | null)[];
30 ageGradeBands: Uint8Array;
31 safes: Uint8Array;
32 deleteds: Uint8Array;
33}
34
35export interface PersonExtendedCols {
36 ids: Uint16Array;
37 descriptions: (string | null)[];
38 birthDates: (string | null)[];
39 deathDates: (string | null)[];
40 nationalitys: (string | null)[];
41 wikiUrls: (string | null)[];
42 isniIds: (string | null)[];
43 orcidIds: (string | null)[];
44}
45
46export interface PersonProvCols {
47 ids: Uint16Array;
48 fields: Record<string, Uint8Array>;
49}
50
51export interface PersonInput {
52 id: number;
53 title: string | null;
54 description: string | null;
55 originalLang: string | null;
56 previewTxId: string | null;
57 ageGradeBand: number;
58 safe: boolean;
59 deleted: boolean;
60 birthDate: string | null;
61 deathDate: string | null;
62 nationality: string | null;
63 wikiUrl: string | null;
64 isniId: string | null;
65 orcidId: string | null;
66}
67export function serializePersonSlim(records: PersonInput[]): ArrayBuffer {
68 return commonSerializeSlim(schema, records, currentLayout());
69}
70export function serializePersonExtended(records: PersonInput[]): ArrayBuffer {
71 return commonSerializeExtended(schema, records, currentLayout());
72}
73export function serializePersonProv(records: PersonInput[]): ArrayBuffer {
74 return commonSerializeProv(schema, records);
75}
76
77export class Person extends Orm {
78 static readonly type: number = 1;
79 static readonly UID_STRATEGY = 'standards-first' as const;
80 static readonly STANDARD_PRIORITY = ["isni","orcid"] as const;
81
82 static readonly serializeSlim = serializePersonSlim;
83 static readonly serializeExtended = serializePersonExtended;
84 static readonly serializeProv = serializePersonProv;
85
86 constructor(json: CommonOrmJson | SerializedCommonOrmJson, creatorUsername?: string) {
87 super(Person.type, json, creatorUsername);
88 }
89
90 /** Synchronous LRU read โ throws on miss (use LoadAsync to re-hydrate). */
91 static Load(id: uid, creatorUsername?: string): Person {
92 return getRecord(Person.type, id, creatorUsername) as Person;
93 }
94
95 static Has(id: uid, creatorUsername?: string): boolean {
96 return hasRecord(Person.type, id, creatorUsername);
97 }
98
99 /** On-demand hydration from the worker after LRU eviction (SPEC ยง2.5). */
100 static async LoadAsync(id: uid, creatorUsername?: string): Promise<Person> {
101 if (hasRecord(Person.type, id, creatorUsername)) {
102 return getRecord(Person.type, id, creatorUsername) as Person;
103 }
104 const thread = PatchInstance.threadInstance;
105 if (!thread) throw new Error("worker thread not initialized โ call PatchInstance.initThread first");
106 const res = await thread.sendRequest({
107 cmd: WorkerCommands.GetRecord,
108 payload: { objectType: Person.type, id }
109 }) as Array<{ lang: Lang, slim?: PersonSlimCols, extended?: PersonExtendedCols, prov?: PersonProvCols }> | null;
110 if (!res || res.length === 0) throw new Error(`Person ${id} not found in worker storage`);
111 const record = NewPersonWithId(id, creatorUsername);
112 for (const data of res) {
113 if (data.slim) record.mergeSlim(data.slim, 0, data.lang);
114 if (data.extended) record.mergeExtended(data.extended, 0, data.lang);
115 if (data.prov) record.mergeProv(data.prov, 0, data.lang);
116 }
117 return record;
118 }
119
120 get birthDate(): string { return this.getProp(43); }
121 set birthDate(value: string) { this.dispatchString(43, value); }
122 getBirthDate(lang: Lang): string { return this.getProp(43, lang); }
123 setBirthDate(value: string, lang: Lang) { this.dispatchString(43, value, lang); }
124
125 get deathDate(): string { return this.getProp(44); }
126 set deathDate(value: string) { this.dispatchString(44, value); }
127 getDeathDate(lang: Lang): string { return this.getProp(44, lang); }
128 setDeathDate(value: string, lang: Lang) { this.dispatchString(44, value, lang); }
129
130 get nationality(): string { return this.getProp(45); }
131 set nationality(value: string) { this.dispatchString(45, value); }
132 getNationality(lang: Lang): string { return this.getProp(45, lang); }
133 setNationality(value: string, lang: Lang) { this.dispatchString(45, value, lang); }
134
135 get wikiUrl(): string { return this.getProp(46); }
136 set wikiUrl(value: string) { this.dispatchString(46, value); }
137 getWikiUrl(lang: Lang): string { return this.getProp(46, lang); }
138 setWikiUrl(value: string, lang: Lang) { this.dispatchString(46, value, lang); }
139
140 get isniId(): string | null { return this.getProp(47) ?? null; }
141 set isniId(value: string | null) { this.dispatchString(47, value ?? ""); }
142 getIsniId(lang: Lang): string | null { return this.getProp(47, lang) ?? null; }
143 setIsniId(value: string | null, lang: Lang) { this.dispatchString(47, value ?? "", lang); }
144
145 get orcidId(): string | null { return this.getProp(48) ?? null; }
146 set orcidId(value: string | null) { this.dispatchString(48, value ?? ""); }
147 getOrcidId(lang: Lang): string | null { return this.getProp(48, lang) ?? null; }
148 setOrcidId(value: string | null, lang: Lang) { this.dispatchString(48, value ?? "", lang); }
149
150 get inAuthorOfIds(): Array<uid> {
151 return Array.from(this._in.get(2)!.values());
152 }
153
154 get inAuthorOf(): Array<Book> {
155 return this.inAuthorOfIds.map(id => Book.Load(id));
156 }
157
158 isInAuthorOf(id: uid): boolean {
159 return this._in.get(2)!.has(id);
160 }
161
162 addIntoAuthorOf(id: uid) {
163 if (this.isInAuthorOf(id)) return;
164 const op: EditRelationObj = {
165 operation: PatchOperation.EditRelation,
166 objectType: Book.type,
167 objectId: id,
168 langId: 0,
169 relationId: 1, // canonical: Book.authors
170 action: PatchAction.Add,
171 targetId: this.id,
172 };
173 if (hasRecord(Book.type, id)) {
174 (getRecord(Book.type, id) as Book).patch(op);
175 }
176 this.applyRelationRaw('in', 2, PatchAction.Add, id);
177 PatchInstance.addPatch(op);
178 }
179
180 removeFromAuthorOf(id: uid) {
181 if (!this.isInAuthorOf(id)) return;
182 const op: EditRelationObj = {
183 operation: PatchOperation.EditRelation,
184 objectType: Book.type,
185 objectId: id,
186 langId: 0,
187 relationId: 1, // canonical: Book.authors
188 action: PatchAction.Remove,
189 targetId: this.id,
190 };
191 if (hasRecord(Book.type, id)) {
192 (getRecord(Book.type, id) as Book).patch(op);
193 }
194 this.applyRelationRaw('in', 2, PatchAction.Remove, id);
195 PatchInstance.addPatch(op);
196 }
197
198
199 // โโ UID methods โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
200 toPID(): string {
201 const scope = (this.id & 0x80000000) ? 'U' : 'C';
202 return `DL:${scope}:PR:${encodePID('PR', this.id)}`;
203 }
204 toNativePID(): string { return this.toPID(); }
205
206 static fromPID(pid: string): { wireId: number } | null {
207 try {
208 if (!pid.startsWith('DL:')) return decodePID('PR', pid);
209 const parts = pid.split(':');
210 if (parts.length >= 4 && parts[2] === 'PR') {
211 return decodePID('PR', parts[3]);
212 }
213 return null;
214 } catch {
215 return null;
216 }
217 }
218 // โโ Inherited from isni standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
219 get isniNormalized(): string | null {
220 return this.isniId ? ISNIAdapter.normalize(this.isniId) : null;
221 }
222 validateIsni(): ReturnType<typeof ISNIAdapter.validate> {
223 return ISNIAdapter.validate(this.isniId);
224 }
225 // โโ Inherited from orcid standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
226 get orcidNormalized(): string | null {
227 return this.orcidId ? ORCIDAdapter.normalize(this.orcidId) : null;
228 }
229 validateOrcid(): ReturnType<typeof ORCIDAdapter.validate> {
230 return ORCIDAdapter.validate(this.orcidId);
231 }
232 sfcuid(): string {
233 if (this.isniId) return `isni:${ISNIAdapter.normalize(this.isniId)}`;
234 if (this.orcidId) return `orcid:${ORCIDAdapter.normalize(this.orcidId)}`;
235 return this.toNativePID();
236 }
237 get identityCluster(): RecordIdentityCluster {
238 const primary = this.sfcuid();
239 const allAliases = [
240 this.isniId ? `isni:${ISNIAdapter.normalize(this.isniId)}` : null,
241 this.orcidId ? `orcid:${ORCIDAdapter.normalize(this.orcidId)}` : null,
242 this.toNativePID()
243 ].filter(Boolean) as string[];
244 return {
245 sfcuid: primary,
246 native: this.toNativePID(),
247 aliases: allAliases.filter(a => a !== primary),
248 wireId: this.id,
249 };
250 }
251
252 // Merge methods are now implemented in Orm using the schema definition.
253
254}
255
256
257export const NewPersonWithId = (id: uid, creatorUsername?: string): Person => {
258 if (hasRecord(Person.type, id, creatorUsername)) {
259 return getRecord(Person.type, id, creatorUsername) as Person;
260 }
261 const record = new Person(Person.createNewRequest(id), creatorUsername);
262 addRecord(Person.type, record, creatorUsername);
263 return record;
264}
265