88 lines
3.4 KiB
JavaScript
88 lines
3.4 KiB
JavaScript
(function (root, factory) {
|
|
const createVoiceTranscriptStore = factory(root.indexedDB);
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = createVoiceTranscriptStore;
|
|
else root.createVoiceTranscriptStore = createVoiceTranscriptStore;
|
|
})(typeof globalThis !== 'undefined' ? globalThis : this, function buildFactory(defaultIndexedDB) {
|
|
const dbName = 'stackchain-voice-transcripts-v1';
|
|
const STORE_NAME = 'checkpoints';
|
|
const MAX_TRANSCRIPT_LENGTH = 10255;
|
|
|
|
function requestResult(request) {
|
|
return new Promise((resolve, reject) => {
|
|
request.onsuccess = () => resolve(request.result);
|
|
request.onerror = () => reject(request.error || new Error('Private transcript storage failed.'));
|
|
});
|
|
}
|
|
|
|
function createIndexedDbTransaction(indexedDB) {
|
|
if (!indexedDB) return null;
|
|
let databasePromise = null;
|
|
function openDatabase() {
|
|
if (databasePromise) return databasePromise;
|
|
databasePromise = new Promise((resolve, reject) => {
|
|
const request = indexedDB.open(dbName, 1);
|
|
request.onupgradeneeded = () => {
|
|
if (!request.result.objectStoreNames.contains(STORE_NAME)) {
|
|
request.result.createObjectStore(STORE_NAME, {keyPath:'login'});
|
|
}
|
|
};
|
|
request.onsuccess = () => resolve(request.result);
|
|
request.onerror = () => reject(request.error || new Error('Private transcript storage is unavailable.'));
|
|
});
|
|
return databasePromise;
|
|
}
|
|
return async (work, mode = 'readonly') => {
|
|
const database = await openDatabase();
|
|
const transaction = database.transaction(STORE_NAME, mode);
|
|
const store = transaction.objectStore(STORE_NAME);
|
|
const completed = new Promise((resolve, reject) => {
|
|
transaction.oncomplete = () => resolve();
|
|
transaction.onerror = () => reject(transaction.error || new Error('Private transcript storage failed.'));
|
|
transaction.onabort = () => reject(transaction.error || new Error('Private transcript storage was interrupted.'));
|
|
});
|
|
const result = await work({
|
|
get:key => requestResult(store.get(key)),
|
|
put:value => requestResult(store.put(value)),
|
|
delete:key => requestResult(store.delete(key)),
|
|
});
|
|
await completed;
|
|
return result;
|
|
};
|
|
}
|
|
|
|
function normalizeLogin(value) {
|
|
return String(value || '').trim().toLowerCase();
|
|
}
|
|
|
|
function normalizeTranscript(value) {
|
|
return String(value || '').replace(/\s+/g, ' ').trim().slice(0, MAX_TRANSCRIPT_LENGTH);
|
|
}
|
|
|
|
function createVoiceTranscriptStore({transaction = createIndexedDbTransaction(defaultIndexedDB)} = {}) {
|
|
async function load(login) {
|
|
const key = normalizeLogin(login);
|
|
if (!key || !transaction) return '';
|
|
const record = await transaction(store => store.get(key));
|
|
return normalizeTranscript(record?.transcript);
|
|
}
|
|
|
|
async function save(login, transcript) {
|
|
const key = normalizeLogin(login);
|
|
const value = normalizeTranscript(transcript);
|
|
if (!key || !value || !transaction) return;
|
|
await transaction(store => store.put({login:key, transcript:value}), 'readwrite');
|
|
}
|
|
|
|
async function clear(login) {
|
|
const key = normalizeLogin(login);
|
|
if (!key || !transaction) return;
|
|
await transaction(store => store.delete(key), 'readwrite');
|
|
}
|
|
|
|
return {load, save, clear};
|
|
}
|
|
|
|
createVoiceTranscriptStore.databaseName = dbName;
|
|
return createVoiceTranscriptStore;
|
|
});
|