feat(electron): shared storage (#7492)

This commit is contained in:
EYHN
2024-07-15 03:21:08 +00:00
parent 0f1409756e
commit dca88e24fe
22 changed files with 411 additions and 15 deletions
@@ -1,12 +1,14 @@
import { contextBridge } from 'electron';
import { affine, appInfo, getElectronAPIs } from './electron-api';
import { sharedStorage } from './shared-storage';
const { apis, events } = getElectronAPIs();
contextBridge.exposeInMainWorld('appInfo', appInfo);
contextBridge.exposeInMainWorld('apis', apis);
contextBridge.exposeInMainWorld('events', events);
contextBridge.exposeInMainWorld('sharedStorage', sharedStorage);
try {
contextBridge.exposeInMainWorld('affine', affine);
@@ -0,0 +1,87 @@
import { MemoryMemento } from '@toeverything/infra';
import { ipcRenderer } from 'electron';
const initialGlobalState = ipcRenderer.sendSync(
'sharedStorage:getAllGlobalState'
);
const initialGlobalCache = ipcRenderer.sendSync(
'sharedStorage:getAllGlobalCache'
);
function invokeWithCatch(key: string, ...args: any[]) {
ipcRenderer.invoke(key, ...args).catch(err => {
console.error(`Failed to invoke ${key}`, err);
});
}
function createSharedStorageApi(
init: Record<string, any>,
event: string,
api: {
del: string;
clear: string;
set: string;
}
) {
const memory = new MemoryMemento();
memory.setAll(init);
ipcRenderer.on(`sharedStorage:${event}`, (_event, updates) => {
for (const [key, value] of Object.entries(updates)) {
if (value === undefined) {
memory.del(key);
} else {
memory.set(key, value);
}
}
});
return {
del(key: string) {
memory.del(key);
invokeWithCatch(`sharedStorage:${api.del}`, key);
},
clear() {
memory.clear();
invokeWithCatch(`sharedStorage:${api.clear}`);
},
get<T>(key: string): T | undefined {
return memory.get(key);
},
keys() {
return memory.keys();
},
set(key: string, value: unknown) {
memory.set(key, value);
invokeWithCatch(`sharedStorage:${api.set}`, key, value);
},
watch<T>(key: string, cb: (i: T | undefined) => void): () => void {
const subscription = memory.watch(key).subscribe(i => cb(i as T));
return () => subscription.unsubscribe();
},
};
}
export const globalState = createSharedStorageApi(
initialGlobalState,
'onGlobalStateChanged',
{
clear: 'clearGlobalState',
del: 'delGlobalState',
set: 'setGlobalState',
}
);
export const globalCache = createSharedStorageApi(
initialGlobalCache,
'onGlobalCacheChanged',
{
clear: 'clearGlobalCache',
del: 'delGlobalCache',
set: 'setGlobalCache',
}
);
export const sharedStorage = {
globalState,
globalCache,
};