43 lines
1.9 KiB
TypeScript
43 lines
1.9 KiB
TypeScript
import type { CloudPendingOperation, CloudRecoveryState, CloudRecent } from '../../shared/cloud-agents';
|
|
|
|
interface JournalStore {
|
|
get(key: string, fallback: CloudRecoveryState): CloudRecoveryState;
|
|
set(key: string, value: CloudRecoveryState): void;
|
|
}
|
|
let storePromise: Promise<JournalStore> | undefined;
|
|
const loadStore = () => storePromise ??= import('electron-store').then(({ default: Store }) =>
|
|
new Store<Record<string, CloudRecoveryState>>({ name: 'makelore-cloud-recovery' }));
|
|
|
|
/** Main 保存当前账号的未确认业务输入;不保存凭据,也不自动重放。 */
|
|
export class CloudAgentJournal {
|
|
constructor(private readonly store = loadStore) {}
|
|
|
|
async read(accountKey: string): Promise<CloudRecoveryState> {
|
|
return (await this.store()).get(accountKey, { recent: null, pending: [] });
|
|
}
|
|
|
|
private async update(accountKey: string, validate: () => void, change: (value: CloudRecoveryState) => CloudRecoveryState) {
|
|
const store = await this.store();
|
|
validate();
|
|
store.set(accountKey, change(store.get(accountKey, { recent: null, pending: [] })));
|
|
}
|
|
|
|
remember(accountKey: string, recent: CloudRecent | null, validate: () => void) {
|
|
return this.update(accountKey, validate, value => ({ ...value, recent }));
|
|
}
|
|
|
|
put(accountKey: string, entry: CloudPendingOperation, validate: () => void) {
|
|
return this.update(accountKey, validate, value => {
|
|
const existing = value.pending.find(item => item.id === entry.id);
|
|
if (existing && JSON.stringify(existing.input) !== JSON.stringify(entry.input)) {
|
|
throw new Error('同一次待确认操作不能更改输入');
|
|
}
|
|
return { ...value, pending: existing ? value.pending : [...value.pending, entry] };
|
|
});
|
|
}
|
|
|
|
remove(accountKey: string, id: string, validate: () => void) {
|
|
return this.update(accountKey, validate, value => ({ ...value, pending: value.pending.filter(item => item.id !== id) }));
|
|
}
|
|
}
|