Skip to content

Commit

Permalink
feat: improve JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
yuki committed Jan 16, 2023
1 parent b2f8c9d commit beb03ba
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 170 deletions.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kokkoro/jsondb",
"version": "1.0.0",
"version": "1.1.0",
"description": "Local JSON database",
"main": "lib/index.js",
"scripts": {
Expand All @@ -19,11 +19,11 @@
"url": "https://github.com/kokkorojs/jsondb/issues"
},
"homepage": "https://github.com/kokkorojs/jsondb#readme",
"dependencies": {
"chokidar": "^3.5.3"
},
"devDependencies": {
"@types/node": "^18.11.17"
"@types/node": "^18.11.18"
},
"dependencies": {
"@kokkoro/utils": "^0.2.0"
},
"files": [
"lib"
Expand Down
119 changes: 9 additions & 110 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

108 changes: 53 additions & 55 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
import { watch } from 'chokidar';
import { isAbsolute, resolve } from 'path';
import { writeFileSync, readFileSync } from 'fs';
import { writeFile, readFile } from 'fs/promises';
import { isAbsolute, join, resolve } from 'path';
import { writeFileSync, opendirSync, mkdirSync } from 'fs';
import { writeFile } from 'fs/promises';
import { decache, debounce } from '@kokkoro/utils';

export class Database {
public data: {
[k: string]: any;
};

constructor(
/** 文件路径 */
private path: string,
/** 监听文件并热更 */
private watch: boolean = false,
) {
/** 文件夹路径 */
public path: string;
/** JSON 文件路径 */
public filename: string;
// TODO /人◕ ‿‿ ◕人\ 文件备份
// public backup: string;
private data: Record<string, any>;

constructor(path: string) {
this.path = isAbsolute(path) ? path : resolve(path);
this.data = {};
this.filename = join(this.path, 'index.json');
this.data = {
updateTime: new Date(),
};

try {
const data = readFileSync(this.path, 'utf8');
this.data = JSON.parse(data);
opendirSync(path);
} catch (error) {
writeFileSync(this.path, '{}');
mkdirSync(path);
}

try {
this.data = require(this.filename);

if (!this.data.updateTime) {
this.data.updateTime = new Date();
throw new Error();
}
} catch (error) {
writeFileSync(this.filename, JSON.stringify(this.data, null, 2));
}
this.watch && this.watchLocalFile();
}

public get(raw_keys: string, escape: boolean = true) {
let data = this.data;
public async get(raw_keys: string, escape: boolean = true): Promise<Record<string, any> | undefined> {
await this.refreshData();

let data = this.data;
const keys = escape ? raw_keys.split('.') : [raw_keys];
const keys_length = keys.length;

Expand All @@ -43,9 +55,10 @@ export class Database {
return data;
}

public set(raw_keys: string, value: any, escape: boolean = true): this {
let data = this.data;
public async put(raw_keys: string, value: any, escape: boolean = true): Promise<void> {
await this.refreshData();

let data = this.data;
const keys = escape ? raw_keys.split('.') : [raw_keys];
const keys_length = keys.length;

Expand All @@ -63,12 +76,13 @@ export class Database {
}
data = data[key];
}
return this;
await this.writeLocalFile();
}

public has(raw_keys: string, escape: boolean = true): boolean {
let data = this.data;
public async has(raw_keys: string, escape: boolean = true): Promise<boolean> {
await this.refreshData();

let data = this.data;
const keys = escape ? raw_keys.split('.') : [raw_keys];
const keys_length = keys.length;

Expand All @@ -83,9 +97,10 @@ export class Database {
return true;
}

public delete(raw_keys: string, escape: boolean = true): this {
let data = this.data;
public async del(raw_keys: string, escape: boolean = true): Promise<void> {
await this.refreshData();

let data = this.data;
const keys = escape ? raw_keys.split('.') : [raw_keys];
const keys_length = keys.length;

Expand All @@ -101,39 +116,22 @@ export class Database {
}
data = data[key];
}
return this;
}

public async write(): Promise<void> {
const localData = JSON.stringify(await this.getLocalData(), null, 2);
const currentData = JSON.stringify(this.data, null, 2);

if (localData === currentData) {
return;
}
return writeFile(this.path, currentData);
await this.writeLocalFile();
}

/**
* 读取本地文件
*
* @returns 本地数据字符串
*/
private getLocalData(): Promise<string> {
return readFile(this.path, 'utf8');
private async writeLocalFile(): Promise<void> {
this.data.updateTime = new Date();
return writeFile(this.filename, JSON.stringify(this.data, null, 2));
}

/**
* 监听文件热更
*
* @returns
* 刷新数据
*/
private watchLocalFile() {
return watch(this.path).on('change', async () => {
try {
const data = await this.getLocalData();
this.data = JSON.parse(data);
} catch (error) { }
private async refreshData(): Promise<void> {
await new Promise<void>((resolve) => {
decache(this.filename);
this.data = require(this.filename);
resolve();
});
}
}

0 comments on commit beb03ba

Please sign in to comment.