Update cache for join and split nodes.

Use StorageCache in App.js as safe interface to localStorage.
This commit is contained in:
Ian Arawjo 2023-11-27 20:14:34 -05:00
parent fddc63338f
commit 622509188f
4 changed files with 28 additions and 14 deletions

View File

@ -300,7 +300,7 @@ const App = () => {
// NOTE: This currently only saves the front-end state. Cache files
// are not pulled or overwritten upon loading from localStorage.
const flow = rf.toObject();
localStorage.setItem('chainforge-flow', JSON.stringify(flow));
StorageCache.saveToLocalStorage('chainforge-flow', flow);
// Attempt to save the current state of the back-end state,
// the StorageCache. (This does LZ compression to save space.)
@ -342,7 +342,7 @@ const App = () => {
setEdges(flow.edges || []);
// Save flow that user loaded to autosave cache, in case they refresh the browser
localStorage.setItem('chainforge-flow', JSON.stringify(flow));
StorageCache.saveToLocalStorage('chainforge-flow', flow);
StorageCache.saveToLocalStorage('chainforge-state');
}
};
@ -350,10 +350,10 @@ const App = () => {
return localStorage.getItem('chainforge-flow') !== null;
};
const loadFlowFromAutosave = async (rf_inst) => {
const saved_flow = localStorage.getItem('chainforge-flow');
const saved_flow = StorageCache.loadFromLocalStorage('chainforge-flow', false);
if (saved_flow) {
StorageCache.loadFromLocalStorage('chainforge-state');
loadFlow(JSON.parse(saved_flow), rf_inst);
loadFlow(saved_flow, rf_inst);
}
};

View File

@ -8,7 +8,8 @@ import { IconArrowMerge, IconList } from '@tabler/icons-react';
import { Divider, NativeSelect, Text, Popover, Tooltip, Center, Modal, Box } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { escapeBraces } from './backend/template';
import { countNumLLMs } from './backend/utils';
import { countNumLLMs, toStandardResponseFormat } from './backend/utils';
import StorageCache from './backend/cache';
const formattingOptions = [
{value: "\n\n", label:"double newline \\n\\n"},
@ -321,6 +322,11 @@ const JoinNode = ({ data, id }) => {
handleOnConnect();
}, [groupByVar, groupByLLM, formatting])
// Store the outputs to the cache whenever they change
useEffect(() => {
StorageCache.store(`${id}.json`, joinedTexts.map(toStandardResponseFormat));
}, [joinedTexts]);
useEffect(() => {
if (data.refresh && data.refresh === true) {
// Recreate the visualization:

View File

@ -8,9 +8,10 @@ import { IconArrowMerge, IconArrowsSplit, IconList } from '@tabler/icons-react';
import { Divider, NativeSelect, Text, Popover, Tooltip, Center, Modal, Box } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { escapeBraces } from './backend/template';
import { processCSV, deepcopy, deepcopy_and_modify, dict_excluding_key } from "./backend/utils";
import { processCSV, deepcopy, deepcopy_and_modify, dict_excluding_key, toStandardResponseFormat } from "./backend/utils";
import { fromMarkdown } from "mdast-util-from-markdown";
import StorageCache from './backend/cache';
const formattingOptions = [
{value: "list", label:"- list items"},
@ -244,6 +245,11 @@ const SplitNode = ({ data, id }) => {
handleOnConnect();
}, [splitOnFormat])
// Store the outputs to the cache whenever they change
useEffect(() => {
StorageCache.store(`${id}.json`, splitTexts.map(toStandardResponseFormat));
}, [splitTexts]);
useEffect(() => {
if (data.refresh && data.refresh === true) {
// Recreate the visualization:

View File

@ -58,10 +58,11 @@ export default class StorageCache {
* Use loadFromLocalStorage to unpack the localStorage data.
*
* @param localStorageKey The key that will be used in localStorage (default='chainforge')
* @param data Optional. JSON-compatible data to store. If undefined, will store the StorageCache's data. If defined, will only store the passed data.
* @returns True if succeeded, false if failure (e.g., too big for localStorage).
*/
public static saveToLocalStorage(localStorageKey: string='chainforge'): boolean {
const data = StorageCache.getInstance().data;
public static saveToLocalStorage(localStorageKey: string='chainforge', data?: Dict): boolean {
data = data ?? StorageCache.getInstance().data;
const compressed = LZString.compressToUTF16(JSON.stringify(data));
try {
localStorage.setItem(localStorageKey, compressed);
@ -83,22 +84,23 @@ export default class StorageCache {
* Performs lz-string decompression from UTF16 encoding.
*
* @param localStorageKey The key that will be used in localStorage (default='chainforge')
* @returns True if succeeded, false if failure (e.g., key not found).
* @returns Loaded data if succeeded, undefined if failure (e.g., key not found).
*/
public static loadFromLocalStorage(localStorageKey: string='chainforge'): boolean {
public static loadFromLocalStorage(localStorageKey: string='chainforge', setStorageCacheData: boolean=true): boolean {
const compressed = localStorage.getItem(localStorageKey);
if (!compressed) {
console.error(`Could not find cache data in localStorage with key ${localStorageKey}.`);
return false;
return undefined;
}
try {
let data = JSON.parse(LZString.decompressFromUTF16(compressed));
StorageCache.getInstance().data = data;
if (setStorageCacheData)
StorageCache.getInstance().data = data;
console.log('loaded', data);
return true;
return data;
} catch (error) {
console.error(error.message);
return false;
return undefined;
}
}
}