@microphi/json-db 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/json-storage.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAgD,MAAM,MAAM,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAA;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG;IACzC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAA;AAED,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM;;IAwBrC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"json-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/storage/json-storage.ts"],"names":[],"mappings":"AACA,OAAO,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAgD,MAAM,MAAM,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtC;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAA;AAED,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG;IACzC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAA;AAED,qBAAa,WAAW,CAAC,CAAC,SAAS,MAAM;;IAwBrC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,SAAS,CAAC;IA1BpB,YAAY,mBAA0B;IAEtC,KAAK;YAAgC,MAAM;cAAQ,MAAM;QAAgB;IAEzE,IAAI,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAM1B;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAE9B;IAED,OAAO,CAAC,OAAO,CAAiB;gBAItB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAExB,kBAAkB,CAAC,EAAE,OAAO,EAE5B,QAAQ,CAAC,EAAE,MAAM,EACT,SAAS,CAAC,uBAAW;IAgEzB,SAAS;IAMf,GAAG,CAAC,EAAE,EAAE,MAAM;IAIR,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;IA+B7B,MAAM,CAAC,GAAG,GAAG,EAAE,MAAM,EAAE;IAqC7B,QAAQ;IAIR,SAAS;IAqBT,MAAM;YAMQ,WAAW;IAuBzB,OAAO,CAAC,SAAS;IAIX,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAC,SAAS,CAAC;YAsB7B,QAAQ;YAKR,OAAO;CAKtB"}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var _JsonStorage_l;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const list_1 = require("@microphi/list");
|
|
12
|
-
class JsonStorage {
|
|
2
|
+
import { __classPrivateFieldGet } from "tslib";
|
|
3
|
+
import { getDebugger } from '@microphi/debug';
|
|
4
|
+
import MiniSearch from 'minisearch';
|
|
5
|
+
import { close, exists, existsSync, mkdir, openSync, readFileSync, rmSync, unlink, writeFileSync } from 'node:fs';
|
|
6
|
+
import { dirname, join } from 'node:path';
|
|
7
|
+
import { Subject, asapScheduler, debounceTime, from, switchMap } from 'rxjs';
|
|
8
|
+
import { List } from '@microphi/list';
|
|
9
|
+
export class JsonStorage {
|
|
13
10
|
get search() {
|
|
14
11
|
if (!this._search) {
|
|
15
12
|
throw Error(`Need to enable search by passing Minisearch Options to constructor. ${this.entity}`);
|
|
@@ -19,34 +16,38 @@ class JsonStorage {
|
|
|
19
16
|
set search(value) {
|
|
20
17
|
this._search = value;
|
|
21
18
|
}
|
|
22
|
-
constructor(entity, basePath,
|
|
19
|
+
constructor(entity, basePath,
|
|
20
|
+
// minisearch index options
|
|
21
|
+
searchIndexOptions,
|
|
22
|
+
// Debounce time in ms
|
|
23
|
+
debounce, scheduler) {
|
|
23
24
|
this.entity = entity;
|
|
24
25
|
this.basePath = basePath;
|
|
25
26
|
this.scheduler = scheduler;
|
|
26
|
-
_JsonStorage_l.set(this,
|
|
27
|
-
this.syncPending$ = new
|
|
28
|
-
this.index = new
|
|
29
|
-
this.index.operations$.pipe(
|
|
30
|
-
return
|
|
27
|
+
_JsonStorage_l.set(this, getDebugger(`JsonStorage:${this.entity}`));
|
|
28
|
+
this.syncPending$ = new Subject();
|
|
29
|
+
this.index = new List('id', []);
|
|
30
|
+
this.index.operations$.pipe(debounceTime(debounce || 3000, this.scheduler || asapScheduler), switchMap(() => {
|
|
31
|
+
return from(this.saveIndex());
|
|
31
32
|
})).subscribe(() => {
|
|
32
|
-
|
|
33
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, `index has been quiet for ${debounce}ms. Updated`);
|
|
33
34
|
});
|
|
34
|
-
|
|
35
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'creating service');
|
|
35
36
|
if (searchIndexOptions) {
|
|
36
|
-
this._search = new
|
|
37
|
+
this._search = new MiniSearch(searchIndexOptions);
|
|
37
38
|
}
|
|
38
39
|
this.getIndex().then((data) => {
|
|
39
40
|
this.index.upsert(...data);
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, `loaded index for ${data.length} items`);
|
|
42
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'getting documents');
|
|
42
43
|
const documents = [...this.index].map(({ id }) => {
|
|
43
44
|
return this.get(id);
|
|
44
45
|
});
|
|
45
|
-
|
|
46
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, `got ${documents.length} documents`);
|
|
46
47
|
if (searchIndexOptions) {
|
|
47
|
-
|
|
48
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'reading files to generate search index');
|
|
48
49
|
Promise.all(documents).then((actualDocs) => {
|
|
49
|
-
|
|
50
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'rebuilding search index with', actualDocs.length);
|
|
50
51
|
actualDocs.forEach((doc) => {
|
|
51
52
|
try {
|
|
52
53
|
if (doc && doc['id']) {
|
|
@@ -56,20 +57,20 @@ class JsonStorage {
|
|
|
56
57
|
}
|
|
57
58
|
catch (err) {
|
|
58
59
|
console.error('Error while loading entity into search index');
|
|
59
|
-
|
|
60
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, doc);
|
|
60
61
|
// console.error(actualDocs);
|
|
61
62
|
console.error(err);
|
|
62
63
|
}
|
|
63
64
|
});
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'search index rebuilt');
|
|
66
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, `handling ${this._search.documentCount} documents for free search`);
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
}
|
|
70
71
|
async saveIndex() {
|
|
71
72
|
const path = await this.storageFile('index');
|
|
72
|
-
|
|
73
|
+
writeFileSync(path, JSON.stringify([...this.index]));
|
|
73
74
|
return Promise.resolve('ok');
|
|
74
75
|
}
|
|
75
76
|
has(id) {
|
|
@@ -116,7 +117,7 @@ class JsonStorage {
|
|
|
116
117
|
this._search?.remove(doc);
|
|
117
118
|
}
|
|
118
119
|
// finally remove json file
|
|
119
|
-
|
|
120
|
+
unlink(entry.path, (err) => {
|
|
120
121
|
if (err)
|
|
121
122
|
reject(err);
|
|
122
123
|
resolve('ok');
|
|
@@ -135,9 +136,9 @@ class JsonStorage {
|
|
|
135
136
|
this._search.removeAll();
|
|
136
137
|
}
|
|
137
138
|
return new Promise((resolve) => {
|
|
138
|
-
|
|
139
|
+
exists(`${this.basePath}/${this.entity}`, (exists) => {
|
|
139
140
|
if (exists) {
|
|
140
|
-
|
|
141
|
+
rmSync(`${this.basePath}/${this.entity}`, { recursive: true });
|
|
141
142
|
}
|
|
142
143
|
resolve('ok');
|
|
143
144
|
});
|
|
@@ -149,16 +150,16 @@ class JsonStorage {
|
|
|
149
150
|
}
|
|
150
151
|
async storageFile(key) {
|
|
151
152
|
const path = this.buildPath(key);
|
|
152
|
-
const folder =
|
|
153
|
-
if (
|
|
153
|
+
const folder = dirname(path);
|
|
154
|
+
if (existsSync(path)) {
|
|
154
155
|
return Promise.resolve(path);
|
|
155
156
|
}
|
|
156
157
|
return new Promise((resolve, reject) => {
|
|
157
|
-
|
|
158
|
+
mkdir(folder, { recursive: true }, (err) => {
|
|
158
159
|
if (err)
|
|
159
160
|
reject(err);
|
|
160
|
-
const fd =
|
|
161
|
-
|
|
161
|
+
const fd = openSync(path, 'w');
|
|
162
|
+
close(fd, (err) => {
|
|
162
163
|
if (err)
|
|
163
164
|
reject(err);
|
|
164
165
|
resolve(path);
|
|
@@ -167,11 +168,11 @@ class JsonStorage {
|
|
|
167
168
|
});
|
|
168
169
|
}
|
|
169
170
|
buildPath(id) {
|
|
170
|
-
return
|
|
171
|
+
return join(this.basePath, this.entity, `${id}.json`);
|
|
171
172
|
}
|
|
172
173
|
async get(id) {
|
|
173
174
|
const path = await this.storageFile(id);
|
|
174
|
-
const data =
|
|
175
|
+
const data = readFileSync(path, { encoding: 'utf8' });
|
|
175
176
|
let entity;
|
|
176
177
|
try {
|
|
177
178
|
entity = JSON.parse(data);
|
|
@@ -179,22 +180,21 @@ class JsonStorage {
|
|
|
179
180
|
}
|
|
180
181
|
catch (e) {
|
|
181
182
|
// console.log(e);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, `error while trying to load data for item with id ${id}`);
|
|
184
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'item does not exists');
|
|
185
|
+
__classPrivateFieldGet(this, _JsonStorage_l, "f").call(this, 'clearing index');
|
|
185
186
|
this.index.delete({ id, path });
|
|
186
187
|
}
|
|
187
188
|
return Promise.resolve(undefined);
|
|
188
189
|
}
|
|
189
190
|
async getIndex() {
|
|
190
|
-
const index =
|
|
191
|
+
const index = readFileSync(await this.storageFile('index'), { encoding: 'utf8' });
|
|
191
192
|
return JSON.parse(index || '[]');
|
|
192
193
|
}
|
|
193
194
|
async setItem(id, doc) {
|
|
194
|
-
|
|
195
|
+
writeFileSync(join(this.basePath, this.entity, `${id}.json`), JSON.stringify({ id, ...doc }));
|
|
195
196
|
// this.l('wrote doc to disk', id, doc);
|
|
196
197
|
return Promise.resolve('ok');
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
|
-
exports.JsonStorage = JsonStorage;
|
|
200
200
|
_JsonStorage_l = new WeakMap();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microphi/json-db",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Small, fast and simple file based json-db",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"lint": "eslint ./src"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@microphi/debug": "^2.
|
|
32
|
+
"@microphi/debug": "^2.6.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"minisearch": "^6.3.0",
|
|
44
44
|
"rxjs": "~7.8.0"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "6239637f38d555081da1647b962184616010146e"
|
|
47
47
|
}
|