๐ src/models/generated-src/Tag.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 { LCCAdapter } from "@the_library/standard-adapters/lcc";
16import { DDCAdapter } from "@the_library/standard-adapters/ddc";
17import { UDCAdapter } from "@the_library/standard-adapters/udc";
18import { CLCAdapter } from "@the_library/standard-adapters/clc";
19import { BBKAdapter } from "@the_library/standard-adapters/bbk";
20import { TLCAdapter } from "@the_library/standard-adapters/tlc";
21import { CCAdapter } from "@the_library/standard-adapters/cc";
22
23const schema = schemas["Tag"] as ModelDefinition;
24
25Registry.register(schema);
26
27/** propName -> propId (provenance column mapping) */
28export const TAG_PROP_IDS: Record<string, number> = { 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 };
29
30export interface TagSlimCols {
31 ids: Uint16Array;
32 titles: (string | null)[];
33 originalLangs: (string | null)[];
34 previewTxIds: (string | null)[];
35 ageGradeBands: Uint8Array;
36 safes: Uint8Array;
37 deleteds: Uint8Array;
38}
39
40export interface TagExtendedCols {
41 ids: Uint16Array;
42 descriptions: (string | null)[];
43 lccNotations: (string | null)[];
44 ddcNotations: (string | null)[];
45 udcNotations: (string | null)[];
46 clcNotations: (string | null)[];
47 bbkNotations: (string | null)[];
48 tlcNotations: (string | null)[];
49 ccNotations: (string | null)[];
50 // Structured relation tails (parsed from the sidecar tail, not columnar):
51 tags?: number[][];
52 books?: number[][];
53}
54
55export interface TagProvCols {
56 ids: Uint16Array;
57 fields: Record<string, Uint8Array>;
58}
59
60export interface TagInput {
61 id: number;
62 title: string | null;
63 description: string | null;
64 originalLang: string | null;
65 previewTxId: string | null;
66 ageGradeBand: number;
67 safe: boolean;
68 deleted: boolean;
69 lccNotation: string | null;
70 ddcNotation: string | null;
71 udcNotation: string | null;
72 clcNotation: string | null;
73 bbkNotation: string | null;
74 tlcNotation: string | null;
75 ccNotation: string | null;
76 tags: number[];
77 books: number[];
78}
79export function serializeTagSlim(records: TagInput[]): ArrayBuffer {
80 return commonSerializeSlim(schema, records, currentLayout());
81}
82export function serializeTagExtended(records: TagInput[]): ArrayBuffer {
83 return commonSerializeExtended(schema, records, currentLayout());
84}
85export function serializeTagProv(records: TagInput[]): ArrayBuffer {
86 return commonSerializeProv(schema, records);
87}
88
89export class Tag extends Orm {
90 static readonly type: number = 2;
91 static readonly UID_STRATEGY = 'standards-first' as const;
92 static readonly STANDARD_PRIORITY = ["lcc","ddc","udc","clc","bbk","tlc","cc"] as const;
93
94 static readonly serializeSlim = serializeTagSlim;
95 static readonly serializeExtended = serializeTagExtended;
96 static readonly serializeProv = serializeTagProv;
97
98 constructor(json: CommonOrmJson | SerializedCommonOrmJson, creatorUsername?: string) {
99 super(Tag.type, json, creatorUsername);
100 }
101
102 /** Synchronous LRU read โ throws on miss (use LoadAsync to re-hydrate). */
103 static Load(id: uid, creatorUsername?: string): Tag {
104 return getRecord(Tag.type, id, creatorUsername) as Tag;
105 }
106
107 static Has(id: uid, creatorUsername?: string): boolean {
108 return hasRecord(Tag.type, id, creatorUsername);
109 }
110
111 /** On-demand hydration from the worker after LRU eviction (SPEC ยง2.5). */
112 static async LoadAsync(id: uid, creatorUsername?: string): Promise<Tag> {
113 if (hasRecord(Tag.type, id, creatorUsername)) {
114 return getRecord(Tag.type, id, creatorUsername) as Tag;
115 }
116 const thread = PatchInstance.threadInstance;
117 if (!thread) throw new Error("worker thread not initialized โ call PatchInstance.initThread first");
118 const res = await thread.sendRequest({
119 cmd: WorkerCommands.GetRecord,
120 payload: { objectType: Tag.type, id }
121 }) as Array<{ lang: Lang, slim?: TagSlimCols, extended?: TagExtendedCols, prov?: TagProvCols }> | null;
122 if (!res || res.length === 0) throw new Error(`Tag ${id} not found in worker storage`);
123 const record = NewTagWithId(id, creatorUsername);
124 for (const data of res) {
125 if (data.slim) record.mergeSlim(data.slim, 0, data.lang);
126 if (data.extended) record.mergeExtended(data.extended, 0, data.lang);
127 if (data.prov) record.mergeProv(data.prov, 0, data.lang);
128 }
129 return record;
130 }
131
132 get lccNotation(): string | null { return this.getProp(50) ?? null; }
133 set lccNotation(value: string | null) { this.dispatchString(50, value ?? ""); }
134 getLccNotation(lang: Lang): string | null { return this.getProp(50, lang) ?? null; }
135 setLccNotation(value: string | null, lang: Lang) { this.dispatchString(50, value ?? "", lang); }
136
137 get ddcNotation(): string | null { return this.getProp(49) ?? null; }
138 set ddcNotation(value: string | null) { this.dispatchString(49, value ?? ""); }
139 getDdcNotation(lang: Lang): string | null { return this.getProp(49, lang) ?? null; }
140 setDdcNotation(value: string | null, lang: Lang) { this.dispatchString(49, value ?? "", lang); }
141
142 get udcNotation(): string | null { return this.getProp(51) ?? null; }
143 set udcNotation(value: string | null) { this.dispatchString(51, value ?? ""); }
144 getUdcNotation(lang: Lang): string | null { return this.getProp(51, lang) ?? null; }
145 setUdcNotation(value: string | null, lang: Lang) { this.dispatchString(51, value ?? "", lang); }
146
147 get clcNotation(): string | null { return this.getProp(52) ?? null; }
148 set clcNotation(value: string | null) { this.dispatchString(52, value ?? ""); }
149 getClcNotation(lang: Lang): string | null { return this.getProp(52, lang) ?? null; }
150 setClcNotation(value: string | null, lang: Lang) { this.dispatchString(52, value ?? "", lang); }
151
152 get bbkNotation(): string | null { return this.getProp(53) ?? null; }
153 set bbkNotation(value: string | null) { this.dispatchString(53, value ?? ""); }
154 getBbkNotation(lang: Lang): string | null { return this.getProp(53, lang) ?? null; }
155 setBbkNotation(value: string | null, lang: Lang) { this.dispatchString(53, value ?? "", lang); }
156
157 get tlcNotation(): string | null { return this.getProp(54) ?? null; }
158 set tlcNotation(value: string | null) { this.dispatchString(54, value ?? ""); }
159 getTlcNotation(lang: Lang): string | null { return this.getProp(54, lang) ?? null; }
160 setTlcNotation(value: string | null, lang: Lang) { this.dispatchString(54, value ?? "", lang); }
161
162 get ccNotation(): string | null { return this.getProp(55) ?? null; }
163 set ccNotation(value: string | null) { this.dispatchString(55, value ?? ""); }
164 getCcNotation(lang: Lang): string | null { return this.getProp(55, lang) ?? null; }
165 setCcNotation(value: string | null, lang: Lang) { this.dispatchString(55, value ?? "", lang); }
166
167 get inTagsIds(): Array<uid> {
168 return Array.from(this._in.get(0)!.values());
169 }
170
171 get inTags(): Array<Tag> {
172 return this.inTagsIds.map(id => Tag.Load(id));
173 }
174
175 isInTag(id: uid): boolean {
176 return this._in.get(0)!.has(id);
177 }
178
179 addIntoTag(id: uid) {
180 if (this.isInTag(id)) return;
181 const op: EditRelationObj = {
182 operation: PatchOperation.EditRelation,
183 objectType: Tag.type,
184 objectId: id,
185 langId: 0,
186 relationId: 3, // canonical: Tag.tags
187 action: PatchAction.Add,
188 targetId: this.id,
189 };
190 if (hasRecord(Tag.type, id)) {
191 (getRecord(Tag.type, id) as Tag).patch(op);
192 }
193 this.applyRelationRaw('in', 0, PatchAction.Add, id);
194 PatchInstance.addPatch(op);
195 }
196
197 removeFromTag(id: uid) {
198 if (!this.isInTag(id)) return;
199 const op: EditRelationObj = {
200 operation: PatchOperation.EditRelation,
201 objectType: Tag.type,
202 objectId: id,
203 langId: 0,
204 relationId: 3, // canonical: Tag.tags
205 action: PatchAction.Remove,
206 targetId: this.id,
207 };
208 if (hasRecord(Tag.type, id)) {
209 (getRecord(Tag.type, id) as Tag).patch(op);
210 }
211 this.applyRelationRaw('in', 0, PatchAction.Remove, id);
212 PatchInstance.addPatch(op);
213 }
214
215 get tagsIds(): Array<uid> {
216 return Array.from(this._has.get(3)!.values());
217 }
218
219 get tags(): Array<Tag> {
220 return this.tagsIds.map(id => Tag.Load(id));
221 }
222
223 hasTag(id: uid): boolean {
224 return this._has.get(3)!.has(id);
225 }
226
227 addTag(id: uid) {
228 if (this.hasTag(id)) return;
229 this.dispatchRelation(3, PatchAction.Add, id);
230 }
231
232 removeTag(id: uid) {
233 if (!this.hasTag(id)) return;
234 this.dispatchRelation(3, PatchAction.Remove, id);
235 }
236
237 get booksIds(): Array<uid> {
238 return Array.from(this._has.get(4)!.values());
239 }
240
241 get books(): Array<Book> {
242 return this.booksIds.map(id => Book.Load(id));
243 }
244
245 hasBook(id: uid): boolean {
246 return this._has.get(4)!.has(id);
247 }
248
249 addBook(id: uid) {
250 if (this.hasBook(id)) return;
251 this.dispatchRelation(4, PatchAction.Add, id);
252 }
253
254 removeBook(id: uid) {
255 if (!this.hasBook(id)) return;
256 this.dispatchRelation(4, PatchAction.Remove, id);
257 }
258
259
260 // โโ UID methods โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
261 toPID(): string {
262 const scope = (this.id & 0x80000000) ? 'U' : 'C';
263 return `DL:${scope}:TG:${encodePID('TG', this.id)}`;
264 }
265 toNativePID(): string { return this.toPID(); }
266
267 static fromPID(pid: string): { wireId: number } | null {
268 try {
269 if (!pid.startsWith('DL:')) return decodePID('TG', pid);
270 const parts = pid.split(':');
271 if (parts.length >= 4 && parts[2] === 'TG') {
272 return decodePID('TG', parts[3]);
273 }
274 return null;
275 } catch {
276 return null;
277 }
278 }
279 // โโ Inherited from lcc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
280 get lccNormalized(): string | null {
281 return this.lccNotation ? LCCAdapter.normalize(this.lccNotation) : null;
282 }
283 validateLcc(): ReturnType<typeof LCCAdapter.validate> {
284 return LCCAdapter.validate(this.lccNotation);
285 }
286 // โโ Inherited from ddc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
287 get ddcNormalized(): string | null {
288 return this.ddcNotation ? DDCAdapter.normalize(this.ddcNotation) : null;
289 }
290 validateDdc(): ReturnType<typeof DDCAdapter.validate> {
291 return DDCAdapter.validate(this.ddcNotation);
292 }
293 // โโ Inherited from udc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
294 get udcNormalized(): string | null {
295 return this.udcNotation ? UDCAdapter.normalize(this.udcNotation) : null;
296 }
297 validateUdc(): ReturnType<typeof UDCAdapter.validate> {
298 return UDCAdapter.validate(this.udcNotation);
299 }
300 // โโ Inherited from clc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
301 get clcNormalized(): string | null {
302 return this.clcNotation ? CLCAdapter.normalize(this.clcNotation) : null;
303 }
304 validateClc(): ReturnType<typeof CLCAdapter.validate> {
305 return CLCAdapter.validate(this.clcNotation);
306 }
307 // โโ Inherited from bbk standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
308 get bbkNormalized(): string | null {
309 return this.bbkNotation ? BBKAdapter.normalize(this.bbkNotation) : null;
310 }
311 validateBbk(): ReturnType<typeof BBKAdapter.validate> {
312 return BBKAdapter.validate(this.bbkNotation);
313 }
314 // โโ Inherited from tlc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
315 get tlcNormalized(): string | null {
316 return this.tlcNotation ? TLCAdapter.normalize(this.tlcNotation) : null;
317 }
318 validateTlc(): ReturnType<typeof TLCAdapter.validate> {
319 return TLCAdapter.validate(this.tlcNotation);
320 }
321 // โโ Inherited from cc standard โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
322 get ccNormalized(): string | null {
323 return this.ccNotation ? CCAdapter.normalize(this.ccNotation) : null;
324 }
325 validateCc(): ReturnType<typeof CCAdapter.validate> {
326 return CCAdapter.validate(this.ccNotation);
327 }
328 sfcuid(): string {
329 if (this.lccNotation) return `lcc:${LCCAdapter.normalize(this.lccNotation)}`;
330 if (this.ddcNotation) return `ddc:${DDCAdapter.normalize(this.ddcNotation)}`;
331 if (this.udcNotation) return `udc:${UDCAdapter.normalize(this.udcNotation)}`;
332 if (this.clcNotation) return `clc:${CLCAdapter.normalize(this.clcNotation)}`;
333 if (this.bbkNotation) return `bbk:${BBKAdapter.normalize(this.bbkNotation)}`;
334 if (this.tlcNotation) return `tlc:${TLCAdapter.normalize(this.tlcNotation)}`;
335 if (this.ccNotation) return `cc:${CCAdapter.normalize(this.ccNotation)}`;
336 return this.toNativePID();
337 }
338 get identityCluster(): RecordIdentityCluster {
339 const primary = this.sfcuid();
340 const allAliases = [
341 this.lccNotation ? `lcc:${LCCAdapter.normalize(this.lccNotation)}` : null,
342 this.ddcNotation ? `ddc:${DDCAdapter.normalize(this.ddcNotation)}` : null,
343 this.udcNotation ? `udc:${UDCAdapter.normalize(this.udcNotation)}` : null,
344 this.clcNotation ? `clc:${CLCAdapter.normalize(this.clcNotation)}` : null,
345 this.bbkNotation ? `bbk:${BBKAdapter.normalize(this.bbkNotation)}` : null,
346 this.tlcNotation ? `tlc:${TLCAdapter.normalize(this.tlcNotation)}` : null,
347 this.ccNotation ? `cc:${CCAdapter.normalize(this.ccNotation)}` : null,
348 this.toNativePID()
349 ].filter(Boolean) as string[];
350 return {
351 sfcuid: primary,
352 native: this.toNativePID(),
353 aliases: allAliases.filter(a => a !== primary),
354 wireId: this.id,
355 };
356 }
357
358 // Merge methods are now implemented in Orm using the schema definition.
359
360}
361
362
363export const NewTagWithId = (id: uid, creatorUsername?: string): Tag => {
364 if (hasRecord(Tag.type, id, creatorUsername)) {
365 return getRecord(Tag.type, id, creatorUsername) as Tag;
366 }
367 const record = new Tag(Tag.createNewRequest(id), creatorUsername);
368 addRecord(Tag.type, record, creatorUsername);
369 return record;
370}
371