- Create app with
yarn create electron-app my-new-app --template=typescript-webpack
- Install node packaged
- ajv
- nedb-promises
- react
- react-dom
src > Database > Schemas > SchemaName.ts
import { JSONSchemaType } from "ajv";
export interface Talk {
number: string;
title: string;
}
const TalkSchema: JSONSchemaType<Talk> = {
type: "object",
properties: {
number: {
type: "string",
},
title: {
type: "string",
},
},
required: ["number", "title"],
additionalProperties: false,
};
export default TalkSchema;
src > Database > Stores > StoreName.ts
import Datastore from "nedb-promises";
import Ajv, { ValidateFunction } from "ajv";
import TalkSchema, { Talk } from "../Schemas/Talk";
const dbPath = `${process.cwd()}/talks.db`;
const db = Datastore.create({
filename: dbPath,
timestampData: true,
});
const ajv = new Ajv({
allErrors: true,
useDefaults: true,
});
const validator = ajv.compile(TalkSchema);
const talkStoreInstance = {
validate: (data: Talk) => {
return validator(data);
},
readAll: () => {
return db.find({}).exec();
},
create: (data: Talk) => {
const isValid = validator(data);
if (isValid) {
return db.insert(data);
} else {
console.error(`Schema not valid`, data);
}
},
// ... more methods
};
export { talkStoreInstance };
src > index.ts
const mainWindow = new BrowserWindow({
height: 600,
width: 800,
webPreferences: {
nodeIntegration: true,
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
});
src > preload.js
import { contextBridge } from "electron";
import { talkStoreInstance } from "./Database/Stores/TalkStore";
contextBridge.exposeInMainWorld("db", {
talks: talkStoreInstance,
});
src > renderer.js
// The whole file needs only this when using React
import "./index.tsx";
src > index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World!</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
package.json > config > forge > plugins > renderer > entryPoints
[
{
"html": "./src/index.html",
"js": "./src/renderer.ts",
"name": "main_window",
"preload": {
"js": "./src/preload.js"
}
}
]
src > types.d.ts
import { Talk } from "./Database/Schemas/Talk";
export type DB = {
talks: {
readAll:() => Promise<Talk[]>;
create:(data:Talk) => Promise<Talk>;
} ;
};
declare global {
interface Window {
db: DB;
}
}
In Modules / Pages use as
const readTalks = async () => {
const result = await window.db.talks.readAll();
console.log(`All Talks`, result);
};
const addTalk = async () => {
const talk: Talk = {
number: "001",
title: "Asdf",
};
await window.db.talks.create(talk);
readTalks();
};
Use your normal React Setup
index.tsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
document.getElementById("root")
);