Skip to content

Commit 17e8bf1

Browse files
committed
Revert "refactoring ipc"
This reverts commit 6edaa0e.
1 parent 112d4da commit 17e8bf1

File tree

8 files changed

+201
-89
lines changed

8 files changed

+201
-89
lines changed

src/main/lib/ipc.ts

+88-55
Original file line numberDiff line numberDiff line change
@@ -8,65 +8,98 @@ import sqlite from "./store/sqlite";
88
import { getNativeImage } from "./utils";
99
import { XFetchConfig, xfetch } from "./xfetch";
1010

11-
export const ipcHandlers = {
12-
sqlite: {
13-
run: async (_, query: string, params: [] = []) => sqlite.run(query, params),
14-
all: async (_, query: string, params: [] = []) => sqlite.all(query, params),
15-
get: async (_, query: string, params: [] = []) => sqlite.get(query, params),
16-
runAsTransaction: async (_, queries: string[], params: [][]) => sqlite.runAsTransaction(queries, params)
17-
},
18-
blob: {
19-
cards: {
20-
get: async (_, card: string) => blob.cards.get(card),
21-
create: async (_, cardData: CardData, bannerURI: string | null, avatarURI: string | null) =>
22-
blob.cards.create(cardData, bannerURI, avatarURI),
23-
update: async (_, cardID: number, cardData: CardData, bannerURI: string | null, avatarURI: string | null) =>
24-
blob.cards.update(cardID, cardData, bannerURI, avatarURI),
25-
del: async (_, cardID: number) => blob.cards.del(cardID),
26-
export_: async (_, card: string) => blob.cards.export_(card),
27-
import_: async (_, zip: string) => blob.cards.import_(zip)
28-
},
29-
personas: {
30-
get: async (_, persona: string) => blob.personas.get(persona),
31-
post: async (_, data: PersonaFormData) => blob.personas.post(data),
32-
put: async (_, id: number, data: PersonaFormData) => blob.personas.put(id, data)
11+
async function init() {
12+
ipcMain.handle("sqlite.run", async (_, query: string, params: [] = []) => {
13+
return sqlite.run(query, params);
14+
});
15+
ipcMain.handle("sqlite.all", async (_, query: string, params: [] = []) => {
16+
return sqlite.all(query, params);
17+
});
18+
ipcMain.handle("sqlite.get", async (_, query: string, params: [] = []) => {
19+
return sqlite.get(query, params);
20+
});
21+
ipcMain.handle("sqlite.runAsTransaction", async (_, queries: string[], params: [][]) => {
22+
return sqlite.runAsTransaction(queries, params);
23+
});
24+
25+
ipcMain.handle("blob.cards.get", async (_, card: string) => {
26+
return await blob.cards.get(card);
27+
});
28+
29+
ipcMain.handle(
30+
"blob.cards.create",
31+
async (_, cardData: CardData, bannerURI: string | null, avatarURI: string | null) => {
32+
return await blob.cards.create(cardData, bannerURI, avatarURI);
3333
}
34-
},
35-
secret: {
36-
get: async (_, k: string) => secret.get(k),
37-
set: async (_, k: string, v: string) => secret.set(k, v)
38-
},
39-
setting: {
40-
get: async () => setting.get(),
41-
set: async (_, settings: any) => setting.set(settings)
42-
},
43-
xfetch: {
44-
post: async (_, url: string, body?: object, headers?: Record<string, string>, config?: XFetchConfig) =>
45-
xfetch.post(url, body, headers, config),
46-
get: async (_, url: string, headers?: Record<string, string>, config?: XFetchConfig) =>
47-
xfetch.get(url, headers, config),
48-
abort: async (_, uuid: string) => xfetch.abort(uuid)
49-
},
50-
utils: {
51-
openURL: async (_, url: string) => shell.openExternal(url),
52-
getNativeImage: async (_, path: string) => getNativeImage(path)
53-
}
54-
};
34+
);
5535

56-
// Recurse through the ipcHandlers object and register all handlers with ipcMain
57-
function registerHandlers(handlers: any, prefix = "") {
58-
for (const [key, handler] of Object.entries(handlers)) {
59-
const channel = prefix ? `${prefix}.${key}` : key;
60-
if (typeof handler === "function") {
61-
ipcMain.handle(channel, (_, ...args) => handler(...args));
62-
} else {
63-
registerHandlers(handler, channel);
36+
ipcMain.handle(
37+
"blob.cards.update",
38+
async (_, cardID: number, cardData: CardData, bannerURI: string | null, avatarURI: string | null) => {
39+
return await blob.cards.update(cardID, cardData, bannerURI, avatarURI);
6440
}
65-
}
66-
}
41+
);
6742

68-
async function init() {
69-
registerHandlers(ipcHandlers);
43+
ipcMain.handle("blob.cards.del", async (_, cardID: number) => {
44+
return await blob.cards.del(cardID);
45+
});
46+
47+
ipcMain.handle("blob.cards.export_", async (_, card: string) => {
48+
return await blob.cards.export_(card);
49+
});
50+
51+
ipcMain.handle("blob.cards.import_", async (_, zip: string) => {
52+
return await blob.cards.import_(zip);
53+
});
54+
55+
ipcMain.handle("blob.personas.get", async (_, persona: string) => {
56+
return await blob.personas.get(persona);
57+
});
58+
ipcMain.handle("blob.personas.post", async (_, data: PersonaFormData) => {
59+
return await blob.personas.post(data);
60+
});
61+
62+
ipcMain.handle("blob.personas.put", async (_, id: number, data: PersonaFormData) => {
63+
return await blob.personas.put(id, data);
64+
});
65+
66+
ipcMain.handle("secret.get", async (_, k: string) => {
67+
return await secret.get(k);
68+
});
69+
70+
ipcMain.handle("secret.set", async (_, k: string, v: string) => {
71+
return await secret.set(k, v);
72+
});
73+
74+
ipcMain.handle(
75+
"xfetch.post",
76+
async (_, url: string, body?: object, headers?: Record<string, string>, config?: XFetchConfig) => {
77+
return await xfetch.post(url, body, headers, config);
78+
}
79+
);
80+
81+
ipcMain.handle("xfetch.get", async (_, url: string, headers?: Record<string, string>, config?: XFetchConfig) => {
82+
return await xfetch.get(url, headers, config);
83+
});
84+
85+
ipcMain.handle("xfetch.abort", async (_, uuid: string) => {
86+
return await xfetch.abort(uuid);
87+
});
88+
89+
ipcMain.handle("utils.openURL", async (_, url: string) => {
90+
return await shell.openExternal(url);
91+
});
92+
93+
ipcMain.handle("utils.getNativeImage", async (_, path: string) => {
94+
return getNativeImage(path);
95+
});
96+
ipcMain.handle("setting.get", async () => {
97+
return await setting.get();
98+
});
99+
100+
ipcMain.handle("setting.set", async (_, settings: any) => {
101+
return await setting.set(settings);
102+
});
70103
}
71104

72105
export default {

src/main/lib/store/secret.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Result } from "@shared/types";
2+
import { isError } from "@shared/utils";
23
import fs from "fs/promises";
34
import { attainable, secretsPath } from "../utils";
45

@@ -14,6 +15,7 @@ async function get(k: string): Promise<Result<string, Error>> {
1415
const secrets = JSON.parse(await fs.readFile(secretsPath, "utf-8"));
1516
return { kind: "ok", value: secrets[k] };
1617
} catch (e) {
18+
isError(e);
1719
return { kind: "err", error: e };
1820
}
1921
}
@@ -25,6 +27,7 @@ async function set(k: string, v: string): Promise<Result<void, Error>> {
2527
await fs.writeFile(secretsPath, JSON.stringify(secrets, null, 2));
2628
return { kind: "ok", value: undefined };
2729
} catch (e) {
30+
isError(e);
2831
return { kind: "err", error: e };
2932
}
3033
}

src/preload/index.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { API } from "./index";
2+
3+
declare global {
4+
interface Window {
5+
api: API;
6+
}
7+
}

src/preload/index.ts

+99-28
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,109 @@
1+
import { PersonaFormData } from "@shared/forms";
2+
import { CardData, PersonaBundle, Result, Settings, UICardBundle } from "@shared/types";
13
import { contextBridge, ipcRenderer } from "electron";
2-
import { ipcHandlers } from "../main/lib/ipc";
4+
import { RunResult } from "../main/lib/store/sqlite";
5+
import { XFetchConfig } from "../main/lib/xfetch";
36

4-
export type API = DeepDelFirstArg<typeof ipcHandlers>;
5-
type DelFirstArg<T> = T extends (arg1: any, ...args: infer P) => infer R ? (...args: P) => R : never;
6-
type DeepDelFirstArg<T> = {
7-
[K in keyof T]: T[K] extends (...args: any[]) => any ? DelFirstArg<T[K]> : DeepDelFirstArg<T[K]>;
8-
};
7+
// Expose API types to the renderer process
8+
export interface API {
9+
sqlite: {
10+
run: (query: string, params?: any[]) => Promise<RunResult>;
11+
all: (query: string, params?: any[]) => Promise<unknown[]>;
12+
get: (query: string, params?: any[]) => Promise<unknown>;
13+
runAsTransaction: (queries: string[], params: any[][]) => Promise<void>;
14+
};
15+
blob: {
16+
cards: {
17+
get: (card: string) => Promise<Result<UICardBundle, Error>>;
18+
create: (
19+
cardData: CardData,
20+
bannerURI: string | null,
21+
avatarURI: string | null
22+
) => Promise<Result<undefined, Error>>;
23+
update: (
24+
cardID: number,
25+
cardData: CardData,
26+
bannerURI: string | null,
27+
avatarURI: string | null
28+
) => Promise<Result<undefined, Error>>;
29+
del: (cardID: number) => Promise<Result<undefined, Error>>;
30+
export_: (card: string) => Promise<Result<void, Error>>;
31+
import_: (zip: string) => Promise<Result<void, Error>>;
32+
};
33+
personas: {
34+
get: (persona: string) => Promise<Result<PersonaBundle, Error>>;
35+
post: (data: PersonaFormData) => Promise<Result<void, Error>>;
36+
put: (id: number, data: PersonaFormData) => Promise<Result<void, Error>>;
37+
rename: (oldName: string, newName: string) => Promise<Result<void, Error>>;
38+
};
39+
};
40+
secret: {
41+
get: (k: string) => Promise<Result<string, Error>>;
42+
set: (k: string, v: string) => Promise<Result<void, Error>>;
43+
};
44+
setting: {
45+
get: () => Promise<Result<Settings, Error>>;
46+
set: (settings: any) => Promise<Result<void, Error>>;
47+
};
48+
xfetch: {
49+
post: (
50+
url: string,
51+
body?: object,
52+
headers?: Record<string, string>,
53+
config?: XFetchConfig
54+
) => Promise<Result<any, Error>>;
55+
get: (url: string, headers?: Record<string, string>, config?: XFetchConfig) => Promise<Result<any, Error>>;
56+
abort: (uuid: string) => Promise<Result<void, Error>>;
57+
};
958

10-
declare global {
11-
interface Window {
12-
api: API;
13-
}
59+
utils: {
60+
openURL: (url: string) => void;
61+
getNativeImage: (path: string) => Promise<Result<Electron.NativeImage, Error>>;
62+
};
1463
}
1564

16-
/**
17-
* Recursively create a proxy object that invokes IPC calls when methods are called.
18-
* The resulting object could be used from the renderer process like so:
19-
*
20-
* @example
21-
* window.api.sqlite.run("SELECT * FROM table");
22-
* window.api.blob.cards.get("cardDirName");
23-
*/
24-
const createAPIProxy = (handlers: any, prefix = ""): any => {
25-
const api: any = {};
26-
for (const key of Object.keys(handlers)) {
27-
const channel = prefix ? `${prefix}.${key}` : key;
28-
if (typeof handlers[key] === "function") {
29-
api[key] = (...args: any[]) => ipcRenderer.invoke(channel, ...args);
30-
} else {
31-
api[key] = createAPIProxy(handlers[key], channel);
65+
const api: API = {
66+
sqlite: {
67+
run: (query, params = []) => ipcRenderer.invoke("sqlite.run", query, params),
68+
all: (query, params = []) => ipcRenderer.invoke("sqlite.all", query, params),
69+
get: (query, params = []) => ipcRenderer.invoke("sqlite.get", query, params),
70+
runAsTransaction: (queries, params) => ipcRenderer.invoke("sqlite.runAsTransaction", queries, params)
71+
},
72+
blob: {
73+
cards: {
74+
get: (card) => ipcRenderer.invoke("blob.cards.get", card),
75+
create: (cardData, bannerURI, avatarURI) =>
76+
ipcRenderer.invoke("blob.cards.create", cardData, bannerURI, avatarURI),
77+
update: (cardID, cardData, bannerURI, avatarURI) =>
78+
ipcRenderer.invoke("blob.cards.update", cardID, cardData, bannerURI, avatarURI),
79+
del: (cardID) => ipcRenderer.invoke("blob.cards.del", cardID),
80+
export_: (card) => ipcRenderer.invoke("blob.cards.export_", card),
81+
import_: (zip) => ipcRenderer.invoke("blob.cards.import_", zip)
82+
},
83+
personas: {
84+
get: (persona) => ipcRenderer.invoke("blob.personas.get", persona),
85+
post: (data) => ipcRenderer.invoke("blob.personas.post", data),
86+
put: (id, data) => ipcRenderer.invoke("blob.personas.put", id, data),
87+
rename: (oldName, newName) => ipcRenderer.invoke("blob.personas.rename", oldName, newName)
3288
}
89+
},
90+
secret: {
91+
get: (k) => ipcRenderer.invoke("secret.get", k),
92+
set: (k, v) => ipcRenderer.invoke("secret.set", k, v)
93+
},
94+
setting: {
95+
get: () => ipcRenderer.invoke("setting.get"),
96+
set: (settings) => ipcRenderer.invoke("setting.set", settings)
97+
},
98+
xfetch: {
99+
post: (url, body, headers, config) => ipcRenderer.invoke("xfetch.post", url, body, headers, config),
100+
get: (url, headers, config) => ipcRenderer.invoke("xfetch.get", url, headers, config),
101+
abort: (uuid) => ipcRenderer.invoke("xfetch.abort", uuid)
102+
},
103+
utils: {
104+
openURL: (url) => ipcRenderer.invoke("utils.openURL", url),
105+
getNativeImage: (path) => ipcRenderer.invoke("utils.getNativeImage", path)
33106
}
34-
return api;
35107
};
36108

37-
const api: API = createAPIProxy(ipcHandlers);
38109
contextBridge.exposeInMainWorld("api", api);

src/shared/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ export type CardData = z.infer<typeof cardSchema>;
7070
// Card Storage
7171
// =========================================================
7272
// Contents of the card directory
73-
export interface CardBundle {
73+
export type CardBundle = {
7474
data: CardData;
7575
avatarURI: string;
7676
bannerURI: string;
77-
}
77+
};
7878

7979
export interface UICardBundle extends CardBundle {
8080
id: string;

tsconfig.json

-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@
44
"compilerOptions":{
55
"noUnusedLocals": false,
66
"noUnusedParameters": false,
7-
"noImplicitAny": false,
87
},
98
}

tsconfig.node.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
3-
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "src/shared/**/*", "src/renderer/**/*"],
3+
"include": ["electron.vite.config.*", "src/main/**/*", "src/preload/**/*", "src/backend/**/*", "src/shared/config.ts", "sandbox/*", "src/shared/**/*", "src/main/lib/xfetch.ts", "src/renderer/**/*"],
44
"compilerOptions": {
55
"composite": true,
66
"strict": true,

tsconfig.web.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
"src/renderer/src/env.d.ts",
55
"src/renderer/src/**/*",
66
"src/shared/**/*",
7-
"src/preload/*.ts",
8-
"src/main/**/*.ts",
97
"src/renderer/src/**/*.tsx",
8+
"src/preload/*.d.ts",
109
"src/shared/config.ts"
1110
, "src/main/lib/xfetch.ts" ],
1211
"compilerOptions": {

0 commit comments

Comments
 (0)