mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Replace object stores for Chroma and token cache
This commit is contained in:
		| @@ -40,6 +40,7 @@ | |||||||
|     <script src="scripts/select2.min.js"></script> |     <script src="scripts/select2.min.js"></script> | ||||||
|     <script src="scripts/seedrandom.min.js"></script> |     <script src="scripts/seedrandom.min.js"></script> | ||||||
|     <script src="scripts/droll.js"></script> |     <script src="scripts/droll.js"></script> | ||||||
|  |     <script src="scripts/localforage.min.js"></script> | ||||||
|     <script type="module" src="scripts/eventemitter.js"></script> |     <script type="module" src="scripts/eventemitter.js"></script> | ||||||
|     <script type="module" src="scripts/power-user.js"></script> |     <script type="module" src="scripts/power-user.js"></script> | ||||||
|     <script type="module" src="scripts/swiped-events.js"></script> |     <script type="module" src="scripts/swiped-events.js"></script> | ||||||
|   | |||||||
| @@ -1,11 +1,11 @@ | |||||||
| import { saveSettingsDebounced, getCurrentChatId, system_message_types, extension_prompt_types, eventSource, event_types, getRequestHeaders, CHARACTERS_PER_TOKEN_RATIO, substituteParams, max_context, } from "../../../script.js"; | import { saveSettingsDebounced, getCurrentChatId, system_message_types, extension_prompt_types, eventSource, event_types, getRequestHeaders, CHARACTERS_PER_TOKEN_RATIO, substituteParams, max_context, } from "../../../script.js"; | ||||||
| import { humanizedDateTime } from "../../RossAscends-mods.js"; | import { humanizedDateTime } from "../../RossAscends-mods.js"; | ||||||
| import { getApiUrl, extension_settings, getContext, doExtrasFetch } from "../../extensions.js"; | import { getApiUrl, extension_settings, getContext, doExtrasFetch } from "../../extensions.js"; | ||||||
| import { getFileText, onlyUnique, splitRecursive, IndexedDBStore } from "../../utils.js"; | import { getFileText, onlyUnique, splitRecursive } from "../../utils.js"; | ||||||
| export { MODULE_NAME }; | export { MODULE_NAME }; | ||||||
|  |  | ||||||
| const MODULE_NAME = 'chromadb'; | const MODULE_NAME = 'chromadb'; | ||||||
| const dbStore = new IndexedDBStore('SillyTavern', MODULE_NAME); | const dbStore = localforage.createInstance({ name: 'SillyTavern_ChromaDB' }); | ||||||
|  |  | ||||||
| const defaultSettings = { | const defaultSettings = { | ||||||
|     strategy: 'original', |     strategy: 'original', | ||||||
| @@ -59,7 +59,7 @@ async function invalidateMessageSyncState(messageId) { | |||||||
|     console.log('CHROMADB: invalidating message sync state', messageId); |     console.log('CHROMADB: invalidating message sync state', messageId); | ||||||
|     const state = await getChatSyncState(); |     const state = await getChatSyncState(); | ||||||
|     state[messageId] = 0; |     state[messageId] = 0; | ||||||
|     await dbStore.put(getCurrentChatId(), state); |     await dbStore.setItem(getCurrentChatId(), state); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function getChatSyncState() { | async function getChatSyncState() { | ||||||
| @@ -69,7 +69,7 @@ async function getChatSyncState() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     const context = getContext(); |     const context = getContext(); | ||||||
|     const chatState = (await dbStore.get(currentChatId)) || []; |     const chatState = (await dbStore.getItem(currentChatId)) || []; | ||||||
|  |  | ||||||
|     // if the chat length has decreased, it means that some messages were deleted |     // if the chat length has decreased, it means that some messages were deleted | ||||||
|     if (chatState.length > context.chat.length) { |     if (chatState.length > context.chat.length) { | ||||||
| @@ -92,7 +92,7 @@ async function getChatSyncState() { | |||||||
|             chatState[i] = 0; |             chatState[i] = 0; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     await dbStore.put(currentChatId, chatState); |     await dbStore.setItem(currentChatId, chatState); | ||||||
|  |  | ||||||
|     return chatState; |     return chatState; | ||||||
| } | } | ||||||
| @@ -304,7 +304,7 @@ async function filterSyncedMessages(splitMessages) { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     console.debug('CHROMADB: sync state', syncState.map((v, i) => ({ id: i, synced: v }))); |     console.debug('CHROMADB: sync state', syncState.map((v, i) => ({ id: i, synced: v }))); | ||||||
|     await dbStore.put(getCurrentChatId(), syncState); |     await dbStore.setItem(getCurrentChatId(), syncState); | ||||||
|  |  | ||||||
|     // remove messages that are already synced |     // remove messages that are already synced | ||||||
|     return splitMessages.filter((_, i) => !removeIndices.includes(i)); |     return splitMessages.filter((_, i) => !removeIndices.includes(i)); | ||||||
| @@ -325,7 +325,7 @@ async function onPurgeClick() { | |||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     if (purgeResult.ok) { |     if (purgeResult.ok) { | ||||||
|         await dbStore.delete(chat_id); |         await dbStore.removeItem(chat_id); | ||||||
|         toastr.success('ChromaDB context has been successfully cleared'); |         toastr.success('ChromaDB context has been successfully cleared'); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								public/scripts/localforage.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								public/scripts/localforage.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -45,7 +45,6 @@ import { | |||||||
| } from "./secrets.js"; | } from "./secrets.js"; | ||||||
|  |  | ||||||
| import { | import { | ||||||
|     IndexedDBStore, |  | ||||||
|     delay, |     delay, | ||||||
|     download, |     download, | ||||||
|     getFileText, |     getFileText, | ||||||
| @@ -121,35 +120,36 @@ const openrouter_website_model = 'OR_Website'; | |||||||
|  |  | ||||||
| let biasCache = undefined; | let biasCache = undefined; | ||||||
| let model_list = []; | let model_list = []; | ||||||
| const objectStore = new IndexedDBStore('SillyTavern', 'chat_completions'); | const objectStore = new localforage.createInstance({ name: "SillyTavern_ChatCompletions" }); | ||||||
|  |  | ||||||
| let tokenCache = {}; | let tokenCache = {}; | ||||||
|  |  | ||||||
| async function loadTokenCache() { | async function loadTokenCache() { | ||||||
|     try { |     try { | ||||||
|         console.debug('Chat Completions: loading token cache from IndexedDB') |         console.debug('Chat Completions: loading token cache') | ||||||
|         tokenCache = await objectStore.get('tokenCache') || {}; |         tokenCache = await objectStore.getItem('tokenCache') || {}; | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         console.log('Chat Completions: unable to load token cache from IndexedDB, using default value', e); |         console.log('Chat Completions: unable to load token cache, using default value', e); | ||||||
|         tokenCache = {}; |         tokenCache = {}; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function saveTokenCache() { | async function saveTokenCache() { | ||||||
|     try { |     try { | ||||||
|         console.debug('Chat Completions: saving token cache to IndexedDB') |         console.debug('Chat Completions: saving token cache') | ||||||
|         await objectStore.put('tokenCache', tokenCache); |         await objectStore.setItem('tokenCache', tokenCache); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         console.log('Chat Completions: unable to save token cache to IndexedDB', e); |         console.log('Chat Completions: unable to save token cache', e); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function resetTokenCache() { | async function resetTokenCache() { | ||||||
|     try { |     try { | ||||||
|         console.debug('Chat Completions: resetting token cache in IndexedDB'); |         console.debug('Chat Completions: resetting token cache'); | ||||||
|         Object.keys(tokenCache).forEach(key => delete tokenCache[key]); |         Object.keys(tokenCache).forEach(key => delete tokenCache[key]); | ||||||
|         await objectStore.delete('tokenCache'); |         await objectStore.removeItem('tokenCache'); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         console.log('Chat Completions: unable to reset token cache in IndexedDB', e); |         console.log('Chat Completions: unable to reset token cache', e); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2799,8 +2799,8 @@ function onProxyPasswordShowClick() { | |||||||
|     $(this).toggleClass('fa-eye-slash fa-eye'); |     $(this).toggleClass('fa-eye-slash fa-eye'); | ||||||
| } | } | ||||||
|  |  | ||||||
| $(document).ready(function () { | $(document).ready(async function () { | ||||||
|     loadTokenCache(); |     await loadTokenCache(); | ||||||
|  |  | ||||||
|     $('#test_api_button').on('click', testApiConnection); |     $('#test_api_button').on('click', testApiConnection); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -370,99 +370,6 @@ export function splitRecursive(input, length, delimitiers = ['\n\n', '\n', ' ', | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| export class IndexedDBStore { |  | ||||||
|     constructor(dbName, storeName) { |  | ||||||
|         this.dbName = dbName; |  | ||||||
|         this.storeName = storeName; |  | ||||||
|         this.db = null; |  | ||||||
|         this.version = Date.now(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async open() { |  | ||||||
|         return new Promise((resolve, reject) => { |  | ||||||
|             const request = indexedDB.open(this.dbName, this.version); |  | ||||||
|  |  | ||||||
|             request.onupgradeneeded = (event) => { |  | ||||||
|                 const db = event.target.result; |  | ||||||
|                 if (!db.objectStoreNames.contains(this.storeName)) { |  | ||||||
|                     db.createObjectStore(this.storeName, { keyPath: null, autoIncrement: false }); |  | ||||||
|                 } |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             request.onsuccess = (event) => { |  | ||||||
|                 console.debug(`IndexedDBStore.open(${this.dbName})`); |  | ||||||
|                 this.db = event.target.result; |  | ||||||
|                 resolve(this.db); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             request.onerror = (event) => { |  | ||||||
|                 console.error(`IndexedDBStore.open(${this.dbName})`); |  | ||||||
|                 reject(event.target.error); |  | ||||||
|             }; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async get(key) { |  | ||||||
|         if (!this.db) await this.open(); |  | ||||||
|  |  | ||||||
|         return new Promise((resolve, reject) => { |  | ||||||
|             const transaction = this.db.transaction(this.storeName, "readonly"); |  | ||||||
|             const objectStore = transaction.objectStore(this.storeName); |  | ||||||
|             const request = objectStore.get(key); |  | ||||||
|  |  | ||||||
|             request.onsuccess = (event) => { |  | ||||||
|                 console.debug(`IndexedDBStore.get(${key})`); |  | ||||||
|                 resolve(event.target.result); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             request.onerror = (event) => { |  | ||||||
|                 console.error(`IndexedDBStore.get(${key})`); |  | ||||||
|                 reject(event.target.error); |  | ||||||
|             }; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async put(key, object) { |  | ||||||
|         if (!this.db) await this.open(); |  | ||||||
|  |  | ||||||
|         return new Promise((resolve, reject) => { |  | ||||||
|             const transaction = this.db.transaction(this.storeName, "readwrite"); |  | ||||||
|             const objectStore = transaction.objectStore(this.storeName); |  | ||||||
|             const request = objectStore.put(object, key); |  | ||||||
|  |  | ||||||
|             request.onsuccess = (event) => { |  | ||||||
|                 console.debug(`IndexedDBStore.put(${key})`); |  | ||||||
|                 resolve(event.target.result); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             request.onerror = (event) => { |  | ||||||
|                 console.error(`IndexedDBStore.put(${key})`); |  | ||||||
|                 reject(event.target.error); |  | ||||||
|             }; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     async delete(key) { |  | ||||||
|         if (!this.db) await this.open(); |  | ||||||
|  |  | ||||||
|         return new Promise((resolve, reject) => { |  | ||||||
|             const transaction = this.db.transaction(this.storeName, "readwrite"); |  | ||||||
|             const objectStore = transaction.objectStore(this.storeName); |  | ||||||
|             const request = objectStore.delete(key); |  | ||||||
|  |  | ||||||
|             request.onsuccess = (event) => { |  | ||||||
|                 console.debug(`IndexedDBStore.delete(${key})`); |  | ||||||
|                 resolve(event.target.result); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             request.onerror = (event) => { |  | ||||||
|                 console.error(`IndexedDBStore.delete(${key})`); |  | ||||||
|                 reject(event.target.error); |  | ||||||
|             }; |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export function isDataURL(str) { | export function isDataURL(str) { | ||||||
|     const regex = /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)*;?)?(base64)?,([a-z0-9!$&',()*+;=\-_%.~:@\/?#]+)?$/i; |     const regex = /^data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)*;?)?(base64)?,([a-z0-9!$&',()*+;=\-_%.~:@\/?#]+)?$/i; | ||||||
|     return regex.test(str); |     return regex.test(str); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user