feat(inventory): add automatic v1→v2 migration on settings/chat load

Integrate inventory migration into persistence layer:
- Call migrateInventory() automatically when loading settings
- Call migrateInventory() automatically when loading chat data
- Save migrated data back to persistence immediately
- Update default reset inventory to v2 format
- Add console logging for migration status

Migration behavior:
- Only runs when FEATURE_FLAGS.useNewInventory is true
- Automatically detects v1 string format and converts to v2
- Handles null/undefined/empty/malformed data gracefully
- Logs migration source (v1, null, default) to console
- Persists migrated inventory immediately after conversion
- Migration runs once per load - subsequent loads see v2

Migration scenarios:
1. Old save with v1 string → migrates to v2.onPerson, saves
2. No save data → uses v2 defaults from state.js
3. Already v2 → no migration, no save
4. Chat data with v1 → migrates to v2, updates chat metadata

Changes:
- MODIFIED: src/core/persistence.js (+29 lines)
  - Updated loadSettings() with migration hook
  - Updated loadChatData() with migration hook
  - Changed default reset inventory from 'None' to v2 object

Part of inventory system v2 implementation
Dependencies: inventory types and migration utility
This commit is contained in:
Lucas 'Paperboy' Rose-Winters
2025-10-17 15:06:53 +11:00
parent 110bdb3b64
commit 39ec36f105
+32 -2
View File
@@ -11,13 +11,16 @@ import {
lastGeneratedData,
setExtensionSettings,
updateExtensionSettings,
setLastGeneratedData
setLastGeneratedData,
FEATURE_FLAGS
} from './state.js';
import { migrateInventory } from '../utils/migration.js';
const extensionName = 'third-party/rpg-companion-sillytavern';
/**
* Loads the extension settings from the global settings object.
* Automatically migrates v1 inventory to v2 format if needed.
*/
export function loadSettings() {
if (power_user.extensions && power_user.extensions[extensionName]) {
@@ -26,6 +29,16 @@ export function loadSettings() {
} else {
// console.log('[RPG Companion] No saved settings found, using defaults');
}
// Migrate inventory if feature flag enabled
if (FEATURE_FLAGS.useNewInventory) {
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
if (migrationResult.migrated) {
console.log(`[RPG Companion] Inventory migrated from ${migrationResult.source} to v2 format`);
extensionSettings.userStats.inventory = migrationResult.inventory;
saveSettings(); // Persist migrated inventory
}
}
}
/**
@@ -94,6 +107,7 @@ export function updateMessageSwipeData() {
/**
* Loads RPG data from the current chat's metadata.
* Automatically migrates v1 inventory to v2 format if needed.
*/
export function loadChatData() {
if (!chat_metadata || !chat_metadata.rpg_companion) {
@@ -107,7 +121,13 @@ export function loadChatData() {
arousal: 0,
mood: '😐',
conditions: 'None',
inventory: 'None'
// Use v2 inventory format for defaults
inventory: {
version: 2,
onPerson: "None",
stored: {},
assets: "None"
}
}
});
setLastGeneratedData({
@@ -136,5 +156,15 @@ export function loadChatData() {
setLastGeneratedData({ ...savedData.lastGeneratedData });
}
// Migrate inventory in chat data if feature flag enabled
if (FEATURE_FLAGS.useNewInventory && extensionSettings.userStats.inventory) {
const migrationResult = migrateInventory(extensionSettings.userStats.inventory);
if (migrationResult.migrated) {
console.log(`[RPG Companion] Chat inventory migrated from ${migrationResult.source} to v2 format`);
extensionSettings.userStats.inventory = migrationResult.inventory;
saveChatData(); // Persist migrated inventory to chat metadata
}
}
// console.log('[RPG Companion] Loaded chat data:', savedData);
}