Skip to content

Commit ef47f4f

Browse files
committed
feat: add local storage (#14)
* feat: add storage * feat: add indexedDB
1 parent 97abfb9 commit ef47f4f

File tree

20 files changed

+557
-40
lines changed

20 files changed

+557
-40
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ module.exports = getESLintConfig('react-ts', {
2424
'@typescript-eslint/parser': ['.ts', '.tsx'],
2525
},
2626
},
27-
});
27+
});

demo.png

3 KB
Loading

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@electron/remote": "2",
1515
"detect-port": "1",
1616
"electrom": "19",
17-
"electron": "22",
17+
"electron": "19",
1818
"electron-json-storage-alt": "18",
1919
"electron-webview-schedule": "18",
2020
"electron-windows": "18",
@@ -26,12 +26,17 @@
2626
"semver": "^7.3.8",
2727
"windows-verify-trust": "1"
2828
},
29+
"optionalDependencies": {
30+
"@journeyapps/sqlcipher": "^5.3.1"
31+
},
2932
"devDependencies": {
3033
"@applint/spec": "^1.2.3",
3134
"@electron/asar": "3",
3235
"@types/jest": "^26.0.24",
3336
"@types/lodash": "^4.14.181",
37+
"@types/node": "^18.15.11",
3438
"cross-env": "^7.0.3",
39+
"dexie": "^3.2.3",
3540
"easy-i18n-cli": "1",
3641
"electron-installer-dmg": "^4.0.0",
3742
"eslint": "7",
@@ -42,6 +47,7 @@
4247
"gulp-nodemon": "^2.5.0",
4348
"husky": "*",
4449
"mocha": "*",
50+
"monitor.js": "^2.0.1",
4551
"nyc": "^15.1.0",
4652
"startserver": "1",
4753
"ts-jest": "^26.5.6",

scripts/electron.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function startElectron(done) {
1313
'package.json',
1414
],
1515
done,
16-
delay: '2500',
16+
delay: '5000',
1717
});
1818
stream
1919
.on('restart', files => {

src/app.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ipcMain, dialog } from 'electron';
1+
import { ipcMain, dialog, shell } from 'electron';
22

33
export default class App {
44
init() {
@@ -13,6 +13,9 @@ export default class App {
1313

1414
bindIPC() {
1515
const { isWin } = this;
16+
ipcMain.on('openExternal', (_, data) => {
17+
shell.openExternal(data);
18+
});
1619
ipcMain.on('start-action', (_, action) => {
1720
if (action === 'electrom') {
1821
require('./electrom')(this);
@@ -40,6 +43,8 @@ export default class App {
4043
return;
4144
}
4245
this.alertWindows();
46+
} else if (action === 'local-storage') {
47+
require('./local-storage')(this);
4348
}
4449
});
4550
}

src/local-storage/index.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict';
2+
3+
const url = require('url');
4+
const path = require('path');
5+
require('@electron/remote/main').initialize();
6+
7+
function initSQLCipher() {
8+
const sqlite3 = require('@journeyapps/sqlcipher').verbose();
9+
console.log(sqlite3);
10+
}
11+
12+
module.exports = (app) => {
13+
const mainUrl = url.format({
14+
pathname: path.join(__dirname, 'renderer', 'main.html'),
15+
protocol: 'file:',
16+
});
17+
const loadingUrl = url.format({
18+
pathname: path.join(__dirname, 'renderer', 'loading.html'),
19+
protocol: 'file:',
20+
});
21+
const windowSize = {
22+
width: 1280,
23+
height: 800,
24+
};
25+
const window = app.windowManager.create({
26+
name: 'local-storage',
27+
loadingView: {
28+
url: loadingUrl,
29+
},
30+
browserWindow: {
31+
...windowSize,
32+
title: 'NoSQL Storage',
33+
show: true,
34+
acceptFirstMouse: true,
35+
webPreferences: {
36+
enableRemoteModule: false,
37+
nodeIntegration: false,
38+
webSecurity: true,
39+
webviewTag: true,
40+
preload: path.join(__dirname, 'renderer', 'preload.js'),
41+
},
42+
},
43+
openDevTools: true,
44+
});
45+
window.loadURL(mainUrl);
46+
initSQLCipher();
47+
};
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict';
2+
3+
window.indexedDBHelper = {
4+
deleteAllIndexedDB: async function () {
5+
const dbs = await window.indexedDB.databases();
6+
for (const db of dbs) {
7+
console.log('delete db start:', db);
8+
try {
9+
const res = await this.deleteDatabase(db.name);
10+
console.log('delete db success:', res);
11+
} catch (e) {
12+
console.log('delete db failed', e);
13+
}
14+
}
15+
return true;
16+
},
17+
deleteDatabase: (name) => {
18+
return new Promise(((resolve, reject) => {
19+
const request = window.indexedDB.deleteDatabase(name);
20+
request.onsuccess = (event) => {
21+
resolve(event);
22+
};
23+
request.onerror = (event) => {
24+
reject(event.target.error);
25+
};
26+
request.onblocked = (event) => {
27+
reject(event.target.error);
28+
};
29+
}));
30+
},
31+
getObjectStore: (dbName, dbVersion = 1, storeName) => {
32+
return new Promise(((resolve, reject) => {
33+
const request = window.indexedDB.open(dbName, dbVersion);
34+
request.onerror = (event) => {
35+
reject(event.target.error);
36+
};
37+
request.onsuccess = (event) => {
38+
const db = event.target.result;
39+
console.log('onsuccess', db.version, db.objectStoreNames);
40+
const objectStore = db.transaction(storeName, 'readwrite')
41+
.objectStore(storeName);
42+
resolve(objectStore);
43+
};
44+
request.onupgradeneeded = (event) => {
45+
const db = event.target.result;
46+
console.log('onupgradeneeded', db.version, db.objectStoreNames);
47+
let objectStore;
48+
if (db.objectStoreNames.contains(storeName)) {
49+
objectStore = db.transaction(storeName, 'readwrite')
50+
.objectStore(storeName);
51+
} else {
52+
objectStore = db.createObjectStore(storeName, {
53+
autoIncrement: true,
54+
});
55+
}
56+
resolve(objectStore);
57+
};
58+
}));
59+
},
60+
addBatchTestData: (objectStore, count = 1000) => {
61+
return new Promise((resolve, reject) => {
62+
for (let i = 1; i <= count; i++) {
63+
const data = {
64+
index1: `index_${i}`,
65+
field1: new Array(100).fill('测试').join(''),
66+
};
67+
const request = objectStore.add(data);
68+
request.onerror = (event) => {
69+
console.error('Error adding data:', event);
70+
};
71+
request.onsuccess = () => {
72+
console.log('Data added successfully');
73+
};
74+
}
75+
objectStore.transaction.oncomplete = () => {
76+
console.log('Transaction completed');
77+
resolve(true);
78+
};
79+
objectStore.transaction.onerror = (event) => {
80+
console.error('Transaction failed:');
81+
reject(event.target.error);
82+
};
83+
});
84+
},
85+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Loading</title>
7+
<style>
8+
::-webkit-scrollbar {
9+
display: none;
10+
}
11+
* {
12+
overflow: hidden;
13+
box-sizing: border-box;
14+
}
15+
html,
16+
body {
17+
background-color: white;
18+
width: 100%;
19+
height: 100%;
20+
margin: 0;
21+
padding: 0;
22+
}
23+
.wrapper {
24+
text-align: center;
25+
padding-top: 100px;
26+
}
27+
</style>
28+
</head>
29+
<body>
30+
<div class="wrapper">
31+
<div class="loading">
32+
loading...
33+
</div>
34+
</div>
35+
</body>
36+
</html>

src/local-storage/renderer/main.css

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
body {
2+
margin: 0;
3+
}
4+
5+
#perf-board {
6+
position: fixed;
7+
width: 204px;
8+
top: 8px;
9+
right: 8px;
10+
}
11+
12+
#wrapper {
13+
margin: 0 auto;
14+
width: 80%;
15+
margin-top: 80px;
16+
}
17+
18+
.logs {
19+
height: 300px;
20+
overflow-y: scroll;
21+
}
22+
23+
.content {
24+
display: flex;
25+
}
26+
27+
.content-item {
28+
flex: 1;
29+
border: 1px solid gray;
30+
padding: 8px;
31+
}
32+
33+
.content-item .logs {
34+
min-height: 90px;
35+
margin: 12px 4px;
36+
padding: 8px;
37+
border: 1px solid gray;
38+
}
39+
40+
.content-item .switch fieldset {
41+
min-height: 110px;
42+
}
43+
44+
.content-item button {
45+
margin-top: 12px;
46+
}
47+
48+
#others {
49+
margin-top: 12px;
50+
}

0 commit comments

Comments
 (0)