update by Silence_Lurker
Init plugin
This commit is contained in:
173
public/client.js
Normal file
173
public/client.js
Normal file
@@ -0,0 +1,173 @@
|
||||
(function() {
|
||||
const extensionName = "Amily-Databin";
|
||||
const apiBaseUrl = `/api/plugins/${extensionName}`;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Private Helper Functions
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Retrieves the current context from SillyTavern and maps it to the expected object name.
|
||||
* This function attempts to get context dynamically from SillyTavern's global objects.
|
||||
*/
|
||||
function _getDynamicObjectName(source) {
|
||||
const { SillyTavern } = window;
|
||||
let context = null;
|
||||
if (SillyTavern && typeof SillyTavern.getContext === 'function') {
|
||||
context = SillyTavern.getContext();
|
||||
} else {
|
||||
console.error(`[${extensionName}] window.SillyTavern.getContext() not found. Dynamic context resolution is not possible.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
console.error(`[${extensionName}] SillyTavern context is null or undefined.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
let resolvedObjectName = null;
|
||||
|
||||
switch (source) {
|
||||
case AmilyDatabin.SourceType.CHAT_LOG:
|
||||
resolvedObjectName = context.chatId;
|
||||
break;
|
||||
case AmilyDatabin.SourceType.CHARACTER_CARD:
|
||||
resolvedObjectName = context.characterId;
|
||||
break;
|
||||
case AmilyDatabin.SourceType.WORLD_BOOK:
|
||||
// From the provided getContext() structure, there is no direct 'current world book name' key.
|
||||
// The user must provide objName for WORLD_BOOK type, or implement custom logic to detect it.
|
||||
console.warn(`[${extensionName}] 'WORLD_BOOK' type's object name cannot be automatically resolved from SillyTavern.getContext(). Please provide 'objName' explicitly.`);
|
||||
break;
|
||||
default:
|
||||
console.error(`[${extensionName}] Unknown source type for dynamic resolution: ${source}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!resolvedObjectName) {
|
||||
console.warn(`[${extensionName}] Could not dynamically resolve object name for source type ${source}. Context key might be missing or not active.`);
|
||||
}
|
||||
return resolvedObjectName;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Public API Method Implementations
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
async function initialize() {
|
||||
try {
|
||||
const response = await fetch(`${apiBaseUrl}/sourcetype`);
|
||||
if (!response.ok) throw new Error(`Failed to fetch source types: ${response.status}`);
|
||||
this.SourceType = await response.json(); // 'this' refers to AmilyDatabin object
|
||||
console.log(`[${extensionName}] Client initialized with source types:`, this.SourceType);
|
||||
} catch (error) {
|
||||
console.error(`[${extensionName}] Initialization failed:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
async function getData(source, fileName, objName = null) {
|
||||
const objectName = objName ?? _getDynamicObjectName(source);
|
||||
if (!objectName) {
|
||||
console.error(`[${extensionName}] 'objName' could not be resolved for getData (Source: ${source}, File: ${fileName}).`);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const queryParams = new URLSearchParams({ source, objName: objectName, file: fileName });
|
||||
const response = await fetch(`${apiBaseUrl}/data?${queryParams.toString()}`);
|
||||
if (response.status === 404) return null;
|
||||
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error(`[${extensionName}] getData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveData(source, fileName, fileContent, objName = null) {
|
||||
const objectName = objName ?? _getDynamicObjectName(source);
|
||||
if (!objectName) {
|
||||
console.error(`[${extensionName}] 'objName' could not be resolved for saveData (Source: ${source}, File: ${fileName}).`);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const response = await fetch(`${apiBaseUrl}/data`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ source, objName: objectName, file: fileName, data: fileContent }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
|
||||
}
|
||||
console.log(`[${extensionName}] Data saved to: ${source}/${objectName}/${fileName}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[${extensionName}] saveData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteData(source, fileName, objName = null) {
|
||||
const objectName = objName ?? _getDynamicObjectName(source);
|
||||
if (!objectName) {
|
||||
console.error(`[${extensionName}] 'objName' could not be resolved for deleteData (Source: ${source}, File: ${fileName}).`);
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const queryParams = new URLSearchParams({ source, objName: objectName, file: fileName });
|
||||
const response = await fetch(`${apiBaseUrl}/data?${queryParams.toString()}`, { method: 'DELETE' });
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
|
||||
}
|
||||
console.log(`[${extensionName}] Data deleted from: ${source}/${objectName}/${fileName}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`[${extensionName}] deleteData failed (Source: ${source}, ObjName: ${objectName}, File: ${fileName}):`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Debug Methods
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
function getDebugInstance() {
|
||||
console.log(`[${extensionName}] AmilyDatabin Instance:`, AmilyDatabin);
|
||||
return AmilyDatabin;
|
||||
}
|
||||
|
||||
function getDebugChatId() {
|
||||
const chatId = _getDynamicObjectName(AmilyDatabin.SourceType.CHAT_LOG);
|
||||
console.log(`[${extensionName}] Current Chat ID (Debug):`, chatId);
|
||||
return chatId;
|
||||
}
|
||||
|
||||
function getDebugCardId() {
|
||||
const cardId = _getDynamicObjectName(AmilyDatabin.SourceType.CHARACTER_CARD);
|
||||
console.log(`[${extensionName}] Current Character Card ID (Debug):`, cardId);
|
||||
return cardId;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Global Object Definition
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
const AmilyDatabin = {
|
||||
SourceType: {},
|
||||
initialize,
|
||||
getData,
|
||||
saveData,
|
||||
deleteData,
|
||||
// Debug methods
|
||||
getDebugInstance,
|
||||
getDebugChatId,
|
||||
getDebugCardId
|
||||
};
|
||||
|
||||
window.AmilyDatabin = AmilyDatabin;
|
||||
|
||||
// Automatically initialize the module.
|
||||
window.AmilyDatabin.initialize.bind(window.AmilyDatabin)();
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user