📄 src/models/uidFactory.ts
D-OPEN SOVEREIGN
1/*
2 * Copyright (c) 2026 DataPond D-Library Pty Ltd. ("The Sanctuary")
3 * Non-Profit Public Library — The World Library
4 *
5 * D-SAFE Certification issued by POND Enterprise.
6 * Published under the D-Open Code Sovereign Licence v1.0 framework
7 * DataPond D-Library All exclusive Right reserved on modifiying the code - CC Attribution to data pond, Non modifiable, Non Commercial.
8 * https://registry.world.bibliotech.com/licence
9 * Source code donated to DataPond D-Library by it's author: data pond.
10 *
11 * Technical Guardian ("The Shield"): Pond Enterprise Pty Ltd. (ACN 694 747 987)
12 * All liability claims about D-SAFE certification issues coming from the published D-Safe direction must be addressed with Pond Enterprise Pty Ltd.
13 * Code Modification automatically voids the certified liability protection provided by Pond Enterprise.
14 */
15const DEVICE_ID_BITS = 12;
16const COUNTER_BITS = 19;
17
18function readFromIndexedDB(db: IDBDatabase, storeName: string, key: string): Promise<any> {
19 return new Promise((resolve, reject) => {
20 const tx = db.transaction(storeName, 'readonly');
21 const store = tx.objectStore(storeName);
22 const req = store.get(key);
23 req.onsuccess = () => resolve(req.result);
24 req.onerror = () => reject(req.error);
25 });
26}
27
28function writeToIndexedDB(db: IDBDatabase, storeName: string, key: string, value: any): Promise<void> {
29 return new Promise((resolve, reject) => {
30 const tx = db.transaction(storeName, 'readwrite');
31 const store = tx.objectStore(storeName);
32 const req = store.put(value, key);
33 req.onsuccess = () => resolve();
34 req.onerror = () => reject(req.error);
35 });
36}
37
38export interface UidFactory {
39 next(): Promise<{ wireId: number; localId: number }>;
40 isUserCreated(wireId: number): boolean;
41}
42
43export function isUserCreated(wireId: number): boolean {
44 return ((wireId >>> 0) & 0x80000000) !== 0;
45}
46
47export class DeviceFingerprintUidFactory implements UidFactory {
48 private readonly deviceId: number;
49 private readonly db: IDBDatabase;
50
51 constructor(deviceId: number, db: IDBDatabase) {
52 this.deviceId = deviceId & 0xFFF;
53 this.db = db;
54 }
55
56 async next(): Promise<{ wireId: number; localId: number }> {
57 return navigator.locks.request('uid-factory', async () => {
58 const state = await readFromIndexedDB(this.db, 'deviceState', 'uidFactory');
59 const count = (state?.counter ?? 0) + 1;
60 if (count > (1 << COUNTER_BITS) - 1) {
61 throw new Error('[UidFactory] Counter exhausted — device has created the maximum number of records');
62 }
63 await writeToIndexedDB(this.db, 'deviceState', 'uidFactory', {
64 deviceId: this.deviceId,
65 counter: count,
66 });
67 const localId = (this.deviceId << COUNTER_BITS) | count;
68 return { wireId: (localId | 0x80000000) >>> 0, localId };
69 });
70 }
71
72 isUserCreated(wireId: number): boolean {
73 return ((wireId >>> 0) & 0x80000000) !== 0;
74 }
75}
76
77export async function loadOrInitUidFactory(db: IDBDatabase): Promise<DeviceFingerprintUidFactory> {
78 return navigator.locks.request('uid-factory', async () => {
79 const state = await readFromIndexedDB(db, 'deviceState', 'uidFactory');
80 const deviceId = state?.deviceId ?? Math.floor(Math.random() * (1 << DEVICE_ID_BITS));
81 if (!state) {
82 await writeToIndexedDB(db, 'deviceState', 'uidFactory', { deviceId, counter: 0 });
83 }
84 return new DeviceFingerprintUidFactory(deviceId, db);
85 });
86}
87