datafolder 1.0.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/README.md +169 -0
- package/index.js +3 -0
- package/package.json +27 -0
- package/sample.js +37 -0
- package/scripts/airbnb.js +73 -0
- package/scripts/airbnb2.js +74 -0
- package/scripts/airbnb2_queries.js +231 -0
- package/scripts/airbnb_queries.js +264 -0
- package/scripts/downloadFile.js +42 -0
- package/scripts/express.js +46 -0
- package/scripts/fastify.js +79 -0
- package/scripts/flights.js +75 -0
- package/scripts/flights2.js +81 -0
- package/scripts/flights2_queries.js +453 -0
- package/scripts/flights_queries.js +403 -0
- package/src/QyAcl.js +252 -0
- package/src/QyAclSaver.js +14 -0
- package/src/QyAclSaver_Worker.js +29 -0
- package/src/QyAclWriter.js +19 -0
- package/src/QyBatch.js +501 -0
- package/src/QyBinWriter.js +140 -0
- package/src/QyCD.js +61 -0
- package/src/QyCache.js +212 -0
- package/src/QyCompressor.js +60 -0
- package/src/QyCompressor_Worker.js +13 -0
- package/src/QyDB.js +122 -0
- package/src/QyDefaultOptions.js +59 -0
- package/src/QyDir.js +192 -0
- package/src/QyFetch.js +38 -0
- package/src/QyFile.js +124 -0
- package/src/QyFileContentUtils.js +175 -0
- package/src/QyFileLogger.js +58 -0
- package/src/QyIndex.js +237 -0
- package/src/QyIndexPropTree.js +92 -0
- package/src/QyIntersectNode.js +48 -0
- package/src/QyItem.js +105 -0
- package/src/QyJsonSaver.js +20 -0
- package/src/QyKVData.js +289 -0
- package/src/QyKVDataCleaner.js +17 -0
- package/src/QyKVDataCleaner_Worker.js +94 -0
- package/src/QyKVDataLoader.js +65 -0
- package/src/QyKVDataSaver.js +17 -0
- package/src/QyKVDataSaver_Worker.js +81 -0
- package/src/QyLogFileSaver.js +14 -0
- package/src/QyLogFileSaver_Worker.js +26 -0
- package/src/QyLogger.js +76 -0
- package/src/QyMessageWorker.js +41 -0
- package/src/QyMessager.js +84 -0
- package/src/QyMessager_Run.js +13 -0
- package/src/QyMod.js +15 -0
- package/src/QyOpRunner.js +73 -0
- package/src/QyQueue.js +60 -0
- package/src/QySaver.js +83 -0
- package/src/QySnapshotCompactor.js +17 -0
- package/src/QySnapshotCompactor_Worker.js +151 -0
- package/src/QySnapshotSaver.js +17 -0
- package/src/QySnapshotSaver_Worker.js +164 -0
- package/src/QySnapshots.js +354 -0
- package/src/QyStructure.js +50 -0
- package/src/QyTrigger.js +133 -0
- package/src/QyUnionNode.js +105 -0
- package/src/QyUtils.js +250 -0
- package/src/QyWorker.js +33 -0
- package/src/hackernews.js +93 -0
- package/src/rpc/evalCode.js +9 -0
- package/src/rpc/getFileContent.js +16 -0
- package/src/rpc/getSubItems.js +32 -0
- package/src/rpc/queryFiles.js +33 -0
- package/src/rpc/reloadRpc.js +1 -0
- package/src/simulate.js +114 -0
- package/src/simulate2.js +110 -0
- package/src/soc_pokec.js +43 -0
- package/static/bootstrap-5.3.8-dist/css/bootstrap.min.css +6 -0
- package/static/bootstrap-5.3.8-dist/js/bootstrap.bundle.js +6312 -0
- package/static/datafolderui/QyStyledElement.js +30 -0
- package/static/datafolderui/QyUIFolderTree.js +203 -0
- package/static/datafolderui/QyUIUtils.js +42 -0
- package/static/datafolderui/display-tree.js +108 -0
- package/static/datafolderui/explore-tree.js +122 -0
- package/static/datafolderui/folder-tree.js +5 -0
- package/static/datafolderui/hscrpt.js +25 -0
- package/static/datafolderui/index.css +6 -0
- package/static/datafolderui/index.html +20 -0
- package/static/datafolderui/json-view.js +74 -0
- package/static/datafolderui/kv-input.js +66 -0
- package/static/datafolderui/list-input.js +52 -0
- package/static/datafolderui/main-page.js +98 -0
- package/static/datafolderui/num-input.js +27 -0
- package/static/datafolderui/query-editor.js +229 -0
- package/static/datafolderui/querySelectorShadowRoot.js +24 -0
- package/static/datafolderui/resizable-input.js +67 -0
- package/static/favicon.ico +0 -0
- package/static/icons-1.13.1/font/bootstrap-icons.min.css +5 -0
- package/static/icons-1.13.1/font/fonts/bootstrap-icons.woff +0 -0
- package/static/icons-1.13.1/font/fonts/bootstrap-icons.woff2 +0 -0
- package/static/json-view/dist/jsonview.js +433 -0
- package/static/tree.js/tree.css +106 -0
- package/static/tree.js/tree.js +374 -0
- package/static/w2ui/dist/w2ui.min.css +2 -0
- package/static/w2ui/src/less/icons/icons.json +1 -0
- package/static/w2ui/src/less/icons/preview.html +33 -0
- package/static/w2ui/src/less/icons/readme.md +15 -0
- package/static/w2ui/src/less/icons/svg/box.svg +3 -0
- package/static/w2ui/src/less/icons/svg/check.svg +3 -0
- package/static/w2ui/src/less/icons/svg/colors.svg +3 -0
- package/static/w2ui/src/less/icons/svg/columns.svg +5 -0
- package/static/w2ui/src/less/icons/svg/cross.svg +4 -0
- package/static/w2ui/src/less/icons/svg/drop.svg +6 -0
- package/static/w2ui/src/less/icons/svg/empty.svg +3 -0
- package/static/w2ui/src/less/icons/svg/eye-dropper.svg +4 -0
- package/static/w2ui/src/less/icons/svg/info.svg +8 -0
- package/static/w2ui/src/less/icons/svg/paste.svg +4 -0
- package/static/w2ui/src/less/icons/svg/pencil.svg +5 -0
- package/static/w2ui/src/less/icons/svg/plus.svg +3 -0
- package/static/w2ui/src/less/icons/svg/reload.svg +5 -0
- package/static/w2ui/src/less/icons/svg/search.svg +3 -0
- package/static/w2ui/src/less/icons/svg/settings.svg +8 -0
- package/static/w2ui/src/less/icons/w2ui-font.css +36 -0
- package/static/w2ui/src/less/icons/w2ui-font.woff +0 -0
- package/static/w2ui/src/less/src/buttons.less +184 -0
- package/static/w2ui/src/less/src/common.less +541 -0
- package/static/w2ui/src/less/src/fields.less +302 -0
- package/static/w2ui/src/less/src/form.less +319 -0
- package/static/w2ui/src/less/src/grid.less +1057 -0
- package/static/w2ui/src/less/src/icons.less +37 -0
- package/static/w2ui/src/less/src/layout.less +86 -0
- package/static/w2ui/src/less/src/mixins.less +87 -0
- package/static/w2ui/src/less/src/popup.less +277 -0
- package/static/w2ui/src/less/src/sidebar.less +343 -0
- package/static/w2ui/src/less/src/tabs.less +145 -0
- package/static/w2ui/src/less/src/toolbar.less +219 -0
- package/static/w2ui/src/less/src/tooltip.less +948 -0
- package/static/w2ui/src/less/w2ui.less +196 -0
- package/static/w2ui/src/locale/az-az.json +114 -0
- package/static/w2ui/src/locale/ba-ba.json +114 -0
- package/static/w2ui/src/locale/bg-bg.json +114 -0
- package/static/w2ui/src/locale/ca-es.json +114 -0
- package/static/w2ui/src/locale/da-dk.json +114 -0
- package/static/w2ui/src/locale/de-de.json +114 -0
- package/static/w2ui/src/locale/en-gb.json +17 -0
- package/static/w2ui/src/locale/en-us.json +17 -0
- package/static/w2ui/src/locale/es-ar.json +115 -0
- package/static/w2ui/src/locale/es-cr.json +119 -0
- package/static/w2ui/src/locale/es-es.json +114 -0
- package/static/w2ui/src/locale/es-mx.json +114 -0
- package/static/w2ui/src/locale/fr-fr.json +114 -0
- package/static/w2ui/src/locale/gl-es.json +114 -0
- package/static/w2ui/src/locale/hr-hr.json +114 -0
- package/static/w2ui/src/locale/hu-hu.json +114 -0
- package/static/w2ui/src/locale/id-id.json +114 -0
- package/static/w2ui/src/locale/it-it.json +114 -0
- package/static/w2ui/src/locale/ja-jp.json +114 -0
- package/static/w2ui/src/locale/kk-kz.json +116 -0
- package/static/w2ui/src/locale/ko-kr.json +114 -0
- package/static/w2ui/src/locale/lt-lt.json +114 -0
- package/static/w2ui/src/locale/nl-nl.json +114 -0
- package/static/w2ui/src/locale/no-no.json +114 -0
- package/static/w2ui/src/locale/pl-pl.json +114 -0
- package/static/w2ui/src/locale/pt-br.json +114 -0
- package/static/w2ui/src/locale/ru-ru.json +116 -0
- package/static/w2ui/src/locale/sk-sk.json +114 -0
- package/static/w2ui/src/locale/sl-si.json +116 -0
- package/static/w2ui/src/locale/sr-rs.json +114 -0
- package/static/w2ui/src/locale/tr-tr.json +114 -0
- package/static/w2ui/src/locale/uk-ua.json +114 -0
- package/static/w2ui/src/locale/zh-cn.json +114 -0
- package/static/w2ui/src/locale/zh-tw.json +114 -0
- package/static/w2ui/src/query.js +583 -0
- package/static/w2ui/src/readme.md +11 -0
- package/static/w2ui/src/w2base.js +311 -0
- package/static/w2ui/src/w2compat.js +207 -0
- package/static/w2ui/src/w2field.js +1854 -0
- package/static/w2ui/src/w2form.js +2411 -0
- package/static/w2ui/src/w2grid.js +8916 -0
- package/static/w2ui/src/w2layout.js +1194 -0
- package/static/w2ui/src/w2locale.js +129 -0
- package/static/w2ui/src/w2popup.js +909 -0
- package/static/w2ui/src/w2sidebar.js +1769 -0
- package/static/w2ui/src/w2tabs.js +669 -0
- package/static/w2ui/src/w2toolbar.js +1180 -0
- package/static/w2ui/src/w2tooltip.js +3134 -0
- package/static/w2ui/src/w2utils.js +2457 -0
package/src/QyCD.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let {
|
|
2
|
+
isString,
|
|
3
|
+
pathSplit
|
|
4
|
+
} = require("./QyUtils.js");
|
|
5
|
+
|
|
6
|
+
class QyCD {
|
|
7
|
+
constructor(r) {
|
|
8
|
+
this.qyCache = r;
|
|
9
|
+
}
|
|
10
|
+
cd(r, i = this.currentDir) {
|
|
11
|
+
return isString(r) && (r = pathSplit(r)), this.cdP(r, i);
|
|
12
|
+
}
|
|
13
|
+
cdP(r, i = this.currentDir) {
|
|
14
|
+
return this.currentDir = this.qyCache.getOrCreateDir(r, i), this;
|
|
15
|
+
}
|
|
16
|
+
dir(r, i = this.currentDir) {
|
|
17
|
+
return isString(r) && (r = pathSplit(r)), this.dirP(r, i);
|
|
18
|
+
}
|
|
19
|
+
dirP(r, i = this.currentDir) {
|
|
20
|
+
return this.qyCache.getDir(r, i);
|
|
21
|
+
}
|
|
22
|
+
indexDir(r, i, t = this.currentDir) {
|
|
23
|
+
return isString(r) && (r = pathSplit(r)), isString(i) && (i = pathSplit(i)),
|
|
24
|
+
this.indexDirP(r, i, t);
|
|
25
|
+
}
|
|
26
|
+
indexDirP(r, i, t = this.currentDir) {
|
|
27
|
+
var e = this.qyCache, r = e.getDir(r, t);
|
|
28
|
+
if (r) {
|
|
29
|
+
t = e.getIndexDir(r);
|
|
30
|
+
if (t) return i && 0 != i.length ? e.getDir(i, t) : t;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
file(r, i = this.currentDir) {
|
|
34
|
+
return isString(r) && (r = pathSplit(r)), this.fileP(r, i);
|
|
35
|
+
}
|
|
36
|
+
fileP(r, i = this.currentDir) {
|
|
37
|
+
return this.qyCache.getFile(r, i);
|
|
38
|
+
}
|
|
39
|
+
triggerFile(r) {
|
|
40
|
+
return this.qyCache.getTriggerFile(r);
|
|
41
|
+
}
|
|
42
|
+
view(r, i, t = this.currentDir) {
|
|
43
|
+
return isString(r) && (r = pathSplit(r)), this.viewP(r, i, t);
|
|
44
|
+
}
|
|
45
|
+
viewP(r, i, t = this.currentDir) {
|
|
46
|
+
return this.qyCache.getFile(r, t)?.view(i);
|
|
47
|
+
}
|
|
48
|
+
queryFiles(r, i, t, e, s = this.currentDir) {
|
|
49
|
+
return this.qyCache.queryFiles(r, i, t, e, s);
|
|
50
|
+
}
|
|
51
|
+
queryFilesMulti(r, i, t, e = this.currentDir) {
|
|
52
|
+
return this.qyCache.queryFilesMulti(r, i, t, e);
|
|
53
|
+
}
|
|
54
|
+
resetCurrentDir() {
|
|
55
|
+
this.currentDir = void 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
Object.assign(module.exports, {
|
|
60
|
+
QyCD: QyCD
|
|
61
|
+
});
|
package/src/QyCache.js
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
let path = require("node:path"), EventEmitter = require("node:events"), QyDir = require("./QyDir.js").QyDir, QyFileLogger = require("./QyFileLogger.js").QyFileLogger, QyKVData = require("./QyKVData.js").QyKVData, {
|
|
2
|
+
QyTriggerNode,
|
|
3
|
+
updateTriggerNodes
|
|
4
|
+
} = require("./QyTrigger.js"), {
|
|
5
|
+
isString,
|
|
6
|
+
lockExclusiveFilePath,
|
|
7
|
+
unlockExclusiveFilePath
|
|
8
|
+
} = require("./QyUtils.js"), dumpStructure = require("./QyStructure.js").dumpStructure, {
|
|
9
|
+
getIndexPropPaths,
|
|
10
|
+
parseNamePathAndQuery
|
|
11
|
+
} = require("./QyIndex.js"), getDefaultOptions = require("./QyDefaultOptions.js").getDefaultOptions, {
|
|
12
|
+
ensureDir,
|
|
13
|
+
SpecialFilePaths
|
|
14
|
+
} = require("./QyUtils.js"), QueryCounter = require("./QyUnionNode.js").QueryCounter, QyKVDataLoader = require("./QyKVDataLoader.js").QyKVDataLoader, requireFromModCode = require("./QyMod.js").requireFromModCode, {
|
|
15
|
+
IndexDirPath,
|
|
16
|
+
TriggerDirPath,
|
|
17
|
+
RpcDirPath
|
|
18
|
+
} = SpecialFilePaths;
|
|
19
|
+
|
|
20
|
+
class QyCache extends EventEmitter {
|
|
21
|
+
constructor(e, r, t) {
|
|
22
|
+
super(), r = {
|
|
23
|
+
...getDefaultOptions("QyCache"),
|
|
24
|
+
...r
|
|
25
|
+
};
|
|
26
|
+
var i = path.join(e, "qykv");
|
|
27
|
+
Object.assign(this, {
|
|
28
|
+
qyDB: t,
|
|
29
|
+
rootFolder: e,
|
|
30
|
+
kvFolder: i,
|
|
31
|
+
rpcFolder: path.join(e, "rpc"),
|
|
32
|
+
options: r,
|
|
33
|
+
rootDir: new QyDir("", !0, void 0, this),
|
|
34
|
+
exclusiveFilePath: path.join(e, ".opened"),
|
|
35
|
+
qyKVData: new QyKVData(i, r, this),
|
|
36
|
+
qyFileLogger: new QyFileLogger(path.join(e, "qylog"), r),
|
|
37
|
+
rpcFunMap: {}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async start() {
|
|
41
|
+
var {
|
|
42
|
+
rootFolder: e,
|
|
43
|
+
kvFolder: r,
|
|
44
|
+
options: t,
|
|
45
|
+
qyKVData: i,
|
|
46
|
+
qyFileLogger: a,
|
|
47
|
+
exclusiveFilePath: o,
|
|
48
|
+
rootDir: s
|
|
49
|
+
} = this;
|
|
50
|
+
logger.log(`Starting at ${e}...`);
|
|
51
|
+
try {
|
|
52
|
+
await ensureDir(r), a.start();
|
|
53
|
+
var [ {
|
|
54
|
+
maxChangeId: g,
|
|
55
|
+
loadedMaxAclNum: n,
|
|
56
|
+
qySnapshots: l,
|
|
57
|
+
aclKeyValueMap: u
|
|
58
|
+
} ] = await Promise.all([ this._loadQyKVData(r, t), lockExclusiveFilePath(o) ]);
|
|
59
|
+
await i.start(g, n, l, u);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
throw a.stop(), e;
|
|
62
|
+
}
|
|
63
|
+
return t.preloadFoldersAtStart && this._preloadFolders(s), this.indexRootDir = s.searchOrCreateSubdir(IndexDirPath),
|
|
64
|
+
this._initTriggers(), this._initRpcs(), t.dumpStructureAtStart && await dumpStructure(path.join(e, "qystruct"), s),
|
|
65
|
+
logger.log("Started."), this;
|
|
66
|
+
}
|
|
67
|
+
async stop() {
|
|
68
|
+
logger.log("Stopping...");
|
|
69
|
+
var {
|
|
70
|
+
qyKVData: e,
|
|
71
|
+
qyFileLogger: r,
|
|
72
|
+
exclusiveFilePath: t
|
|
73
|
+
} = this;
|
|
74
|
+
return await e.stop(), await r.stop(), unlockExclusiveFilePath(t), Object.assign(this, {
|
|
75
|
+
rootDir: void 0,
|
|
76
|
+
indexRootDir: void 0,
|
|
77
|
+
qyKVData: void 0,
|
|
78
|
+
rpcFunMap: void 0,
|
|
79
|
+
qyDB: void 0,
|
|
80
|
+
qyFileLogger: void 0,
|
|
81
|
+
triggerRootDir: void 0,
|
|
82
|
+
rpcRootDir: void 0
|
|
83
|
+
}), logger.log("Stopped."), this;
|
|
84
|
+
}
|
|
85
|
+
increaseChangeId() {
|
|
86
|
+
return this.qyKVData.increaseChangeId();
|
|
87
|
+
}
|
|
88
|
+
decreaseChangeId() {
|
|
89
|
+
this.qyKVData.decreaseChangeId();
|
|
90
|
+
}
|
|
91
|
+
save(e, r, t, i, a) {
|
|
92
|
+
var {
|
|
93
|
+
qyKVData: o,
|
|
94
|
+
qyFileLogger: s
|
|
95
|
+
} = this;
|
|
96
|
+
return t && s.save(e, t), o.save(e, r, i, a);
|
|
97
|
+
}
|
|
98
|
+
getFile(e, r = this.rootDir) {
|
|
99
|
+
return e.isFile ? e : isString(e) ? r.getFile(e) : r.searchFile(e);
|
|
100
|
+
}
|
|
101
|
+
getDir(e, r = this.rootDir) {
|
|
102
|
+
return e.isDir ? e : isString(e) ? r.getSubdir(e) : r.searchSubdir(e);
|
|
103
|
+
}
|
|
104
|
+
getOrCreateFile(e, r = this.rootDir) {
|
|
105
|
+
return e.isFile ? e : isString(e) ? r.getOrCreateFile(e) : r.searchOrCreateFile(e);
|
|
106
|
+
}
|
|
107
|
+
getOrCreateDir(e, r = this.rootDir) {
|
|
108
|
+
return e.isDir ? e : isString(e) ? r.getOrCreateSubdir(e) : r.searchOrCreateSubdir(e);
|
|
109
|
+
}
|
|
110
|
+
getIndexDir(e) {
|
|
111
|
+
return this.indexRootDir.getSubdir(e.fullPathHash);
|
|
112
|
+
}
|
|
113
|
+
getOrCreateIndexDir(e) {
|
|
114
|
+
return this.indexRootDir.getOrCreateSubdir(e.fullPathHash);
|
|
115
|
+
}
|
|
116
|
+
getTriggerFile(e) {
|
|
117
|
+
return this.triggerRootDir.getFile(e);
|
|
118
|
+
}
|
|
119
|
+
getOrCreateTriggerFile(e) {
|
|
120
|
+
return this.triggerRootDir.getOrCreateFile(e);
|
|
121
|
+
}
|
|
122
|
+
getRpcFile(e) {
|
|
123
|
+
return this.rpcRootDir.getFile(e);
|
|
124
|
+
}
|
|
125
|
+
getOrCreateRpcFile(e) {
|
|
126
|
+
return this.rpcRootDir.getOrCreateFile(e);
|
|
127
|
+
}
|
|
128
|
+
insertTriggerToTree(e, r, t, i) {
|
|
129
|
+
var {
|
|
130
|
+
rootDir: a,
|
|
131
|
+
qyDB: o
|
|
132
|
+
} = this, i = requireFromModCode("trigger", e, i, o);
|
|
133
|
+
a.triggerNodes[0].insertTrigger(e, r, t, i), updateTriggerNodes(a, r);
|
|
134
|
+
}
|
|
135
|
+
removeTriggerFromTree(e, r) {
|
|
136
|
+
var t = this.rootDir;
|
|
137
|
+
t.triggerNodes[0].removeTrigger(e, r) && updateTriggerNodes(t, r);
|
|
138
|
+
}
|
|
139
|
+
insertRpc(e, r) {
|
|
140
|
+
var {
|
|
141
|
+
rpcFunMap: t,
|
|
142
|
+
qyDB: i
|
|
143
|
+
} = this, r = requireFromModCode("rpc", e, r, i);
|
|
144
|
+
r && (t[e] = r);
|
|
145
|
+
}
|
|
146
|
+
removeRpc(e) {
|
|
147
|
+
delete this.rpcFunMap[e];
|
|
148
|
+
}
|
|
149
|
+
queryFiles(e, r, t, i, a = this.rootDir) {
|
|
150
|
+
var o = [], t = (isString(r) && null == t && (t = 1), new QueryCounter(t, i));
|
|
151
|
+
return this._queryFiles(e, r, o, t, a), o;
|
|
152
|
+
}
|
|
153
|
+
queryFilesMulti(e, r, t, i = this.rootDir) {
|
|
154
|
+
var a, o, s = [], g = new QueryCounter(r, t);
|
|
155
|
+
for ([ a, o ] of e) this._queryFiles(a, o, s, g, i);
|
|
156
|
+
return s;
|
|
157
|
+
}
|
|
158
|
+
_queryFiles(e, r, t, i, a) {
|
|
159
|
+
var o;
|
|
160
|
+
r && (o = this.options.queryAutoCreateIndex, o = o ? getIndexPropPaths(r) : void 0,
|
|
161
|
+
parseNamePathAndQuery(e, a, o, r, t, i));
|
|
162
|
+
}
|
|
163
|
+
async callRpc(r, e, t) {
|
|
164
|
+
var i, a = this.rpcFunMap[r];
|
|
165
|
+
if (!a) return i = `RPC ${r} not implemented.`, logger.warn(i), new Error(i);
|
|
166
|
+
try {
|
|
167
|
+
return await a(e, t);
|
|
168
|
+
} catch (e) {
|
|
169
|
+
return logger.error(`Calling RPC ${r} failed:`, e), e;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
_preloadFolders(e) {
|
|
173
|
+
var r, t = e.subdirMap;
|
|
174
|
+
for (r in t) {
|
|
175
|
+
var i = t[r];
|
|
176
|
+
i.created && this._preloadFolders(i);
|
|
177
|
+
}
|
|
178
|
+
e._ensureFileMapLoaded();
|
|
179
|
+
}
|
|
180
|
+
_initTriggers() {
|
|
181
|
+
var e, r = this.rootDir;
|
|
182
|
+
r.triggerNodes = [ new QyTriggerNode() ], this.triggerRootDir = r.searchOrCreateSubdir(TriggerDirPath);
|
|
183
|
+
for (e of this.triggerRootDir.fileList) {
|
|
184
|
+
var {
|
|
185
|
+
name: t,
|
|
186
|
+
fileContent: i
|
|
187
|
+
} = e, {
|
|
188
|
+
fileNamePath: i,
|
|
189
|
+
propNamePathList: a,
|
|
190
|
+
modCode: o
|
|
191
|
+
} = i;
|
|
192
|
+
this.insertTriggerToTree(t, i, a, o);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
_initRpcs() {
|
|
196
|
+
this.rpcRootDir = this.rootDir.searchOrCreateSubdir(RpcDirPath);
|
|
197
|
+
for (var e of this.rpcRootDir.fileList) {
|
|
198
|
+
var {
|
|
199
|
+
name: e,
|
|
200
|
+
fileContent: r
|
|
201
|
+
} = e;
|
|
202
|
+
r && (r = r.modCode, r) && this.insertRpc(e, r);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
_loadQyKVData(e, r) {
|
|
206
|
+
return new QyKVDataLoader(e, r).load();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
Object.assign(module.exports, {
|
|
211
|
+
QyCache: QyCache
|
|
212
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
let path = require("node:path"), pipeline = require("node:stream").pipeline, promisify = require("node:util").promisify, {
|
|
2
|
+
createGzip,
|
|
3
|
+
createUnzip
|
|
4
|
+
} = require("node:zlib"), {
|
|
5
|
+
createReadStream,
|
|
6
|
+
createWriteStream
|
|
7
|
+
} = require("node:fs"), fsPromises = require("node:fs/promises"), logger = require("./QyLogger.js").logger, {
|
|
8
|
+
isNotNullObj,
|
|
9
|
+
folderOrFileExists,
|
|
10
|
+
ensureParentDir
|
|
11
|
+
} = require("./QyUtils.js"), runOnceWithWorker = require("./QyWorker.js").runOnceWithWorker, pipe = promisify(pipeline), Zip_File_Extension = ".gz", compressorWorkerJsFileName = "QyCompressor_Worker.js";
|
|
12
|
+
|
|
13
|
+
function compressFile(e, i, r) {
|
|
14
|
+
return isNotNullObj(i) && (r = i, i = void 0), i = i || e + Zip_File_Extension,
|
|
15
|
+
r = r || {}, e.endsWith(Zip_File_Extension) ? (logger.log(`${e} already ends with ${Zip_File_Extension}.`),
|
|
16
|
+
!1) : i.endsWith(Zip_File_Extension) ? runOnceWithWorker(compressorWorkerJsFileName, {
|
|
17
|
+
operation: "compress",
|
|
18
|
+
srcFilePath: e,
|
|
19
|
+
destFilePath: i,
|
|
20
|
+
options: r
|
|
21
|
+
}).promise : (logger.log(`${i} doesn't end with ${Zip_File_Extension}.`), !1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function decompressFile(e, i, r) {
|
|
25
|
+
return e.endsWith(Zip_File_Extension) ? (isNotNullObj(i) && (r = i, i = void 0),
|
|
26
|
+
i = i || e.replace(new RegExp(Zip_File_Extension + "$"), ""), r = r || {}, path.extname(i) == Zip_File_Extension ? (logger.log(`${i} already ends with ${Zip_File_Extension}.`),
|
|
27
|
+
!1) : runOnceWithWorker(compressorWorkerJsFileName, {
|
|
28
|
+
operation: "decompress",
|
|
29
|
+
srcFilePath: e,
|
|
30
|
+
destFilePath: i,
|
|
31
|
+
options: r
|
|
32
|
+
}).promise) : (logger.log(`${e} doesn't end with ${Zip_File_Extension}.`), !1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function runOperation({
|
|
36
|
+
operation: e,
|
|
37
|
+
srcFilePath: i,
|
|
38
|
+
destFilePath: r,
|
|
39
|
+
options: o
|
|
40
|
+
}) {
|
|
41
|
+
var {
|
|
42
|
+
removeSrcAfterSuccess: o,
|
|
43
|
+
override: s
|
|
44
|
+
} = o;
|
|
45
|
+
if (!await folderOrFileExists(i)) throw new Error(i + " doesn't exist.");
|
|
46
|
+
if (!s && await folderOrFileExists(r)) throw new Error(r + " already exists.");
|
|
47
|
+
if (await ensureParentDir(r), await pipe(createReadStream(i), ("compress" == e ? createGzip : createUnzip)(), createWriteStream(r)),
|
|
48
|
+
logger.info(e + `ed ${i} to ${r}.`), o) try {
|
|
49
|
+
await fsPromises.unlink(i), logger.info("Unlinked " + i);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
logger.error(`Failed to unlink ${i}:`, e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
Object.assign(module.exports, {
|
|
56
|
+
Zip_File_Extension: Zip_File_Extension,
|
|
57
|
+
compressFile: compressFile,
|
|
58
|
+
decompressFile: decompressFile,
|
|
59
|
+
runOperation: runOperation
|
|
60
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
let {
|
|
2
|
+
parentPort,
|
|
3
|
+
getEnvironmentData,
|
|
4
|
+
workerData
|
|
5
|
+
} = require("node:worker_threads"), logger = require("./QyLogger.js").logger, runOperation = require("./QyCompressor.js").runOperation;
|
|
6
|
+
|
|
7
|
+
logger.level = getEnvironmentData("logLevel"), (async () => {
|
|
8
|
+
try {
|
|
9
|
+
await runOperation(workerData), parentPort.postMessage(!0);
|
|
10
|
+
} catch (e) {
|
|
11
|
+
parentPort.postMessage(e);
|
|
12
|
+
}
|
|
13
|
+
})();
|
package/src/QyDB.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
let path = require("node:path"), QyFetch = require("./QyFetch.js").QyFetch, QyBatch = require("./QyBatch.js").QyBatch, QyCache = require("./QyCache.js").QyCache, getDefaultOptions = require("./QyDefaultOptions.js").getDefaultOptions, QyCD = require("./QyCD.js").QyCD, Default_RootFolder = path.join(__dirname, "../data/sampleDataFolder");
|
|
2
|
+
|
|
3
|
+
class QyDB extends QyCD {
|
|
4
|
+
constructor(e = Default_RootFolder, t) {
|
|
5
|
+
super(), Object.assign(this, {
|
|
6
|
+
rootFolder: e,
|
|
7
|
+
options: {
|
|
8
|
+
...getDefaultOptions("QyDB"),
|
|
9
|
+
...t
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async start(e) {
|
|
14
|
+
var t;
|
|
15
|
+
return this.qyCache || (e = {
|
|
16
|
+
...this.options,
|
|
17
|
+
...e
|
|
18
|
+
}, t = new QyCache(this.rootFolder, e, this), Object.assign(this, {
|
|
19
|
+
qyCache: t,
|
|
20
|
+
fetch: new QyFetch(t),
|
|
21
|
+
batch: new QyBatch(t, e),
|
|
22
|
+
_immediate: new QyBatch(t, e)
|
|
23
|
+
}), await t.start()), this;
|
|
24
|
+
}
|
|
25
|
+
async stop() {
|
|
26
|
+
var {
|
|
27
|
+
qyCache: e,
|
|
28
|
+
fetch: t,
|
|
29
|
+
batch: r,
|
|
30
|
+
_immediate: i
|
|
31
|
+
} = this;
|
|
32
|
+
e && (await e.stop(), t.qyCache = void 0, r.qyCache = void 0, i.qyCache = void 0,
|
|
33
|
+
Object.assign(this, {
|
|
34
|
+
qyCache: void 0,
|
|
35
|
+
fetch: void 0,
|
|
36
|
+
batch: void 0,
|
|
37
|
+
_immediate: void 0
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
createDir(e) {
|
|
41
|
+
return this._immediate.createDir(e).run(), this.dir(e);
|
|
42
|
+
}
|
|
43
|
+
createDirP(e) {
|
|
44
|
+
return this._immediate.createDirP(e).run(), this.dirP(e);
|
|
45
|
+
}
|
|
46
|
+
createFile(e) {
|
|
47
|
+
return this._immediate.createFile(e).run(), this.file(e);
|
|
48
|
+
}
|
|
49
|
+
createFileP(e) {
|
|
50
|
+
return this._immediate.createFileP(e).run(), this.fileP(e);
|
|
51
|
+
}
|
|
52
|
+
createIndex(e, t) {
|
|
53
|
+
return this._immediate.createIndex(e, t).run();
|
|
54
|
+
}
|
|
55
|
+
createIndexP(e, t) {
|
|
56
|
+
return this._immediate.createIndexP(e, t).run();
|
|
57
|
+
}
|
|
58
|
+
delIndex(e, t) {
|
|
59
|
+
return this._immediate.delIndex(e, t).run();
|
|
60
|
+
}
|
|
61
|
+
delIndexP(e, t) {
|
|
62
|
+
return this._immediate.delIndexP(e, t).run();
|
|
63
|
+
}
|
|
64
|
+
insert(e, t) {
|
|
65
|
+
return this._immediate.insert(e, t).run();
|
|
66
|
+
}
|
|
67
|
+
insertP(e, t) {
|
|
68
|
+
return this._immediate.insertP(e, t).run();
|
|
69
|
+
}
|
|
70
|
+
remove(e, t) {
|
|
71
|
+
return this._immediate.remove(e, t).run();
|
|
72
|
+
}
|
|
73
|
+
removeP(e, t) {
|
|
74
|
+
return this._immediate.removeP(e, t).run();
|
|
75
|
+
}
|
|
76
|
+
replace(e, t) {
|
|
77
|
+
return this._immediate.replace(e, t).run();
|
|
78
|
+
}
|
|
79
|
+
replaceP(e, t) {
|
|
80
|
+
return this._immediate.replaceP(e, t).run();
|
|
81
|
+
}
|
|
82
|
+
delDir(e) {
|
|
83
|
+
return this._immediate.delDir(e).run();
|
|
84
|
+
}
|
|
85
|
+
delDirP(e) {
|
|
86
|
+
return this._immediate.delDirP(e).run();
|
|
87
|
+
}
|
|
88
|
+
delFile(e) {
|
|
89
|
+
return this._immediate.delFile(e).run();
|
|
90
|
+
}
|
|
91
|
+
delFileP(e) {
|
|
92
|
+
return this._immediate.delFileP(e).run();
|
|
93
|
+
}
|
|
94
|
+
delContent(e) {
|
|
95
|
+
return this._immediate.delContent(e).run();
|
|
96
|
+
}
|
|
97
|
+
delContentP(e) {
|
|
98
|
+
return this._immediate.delContentP(e).run();
|
|
99
|
+
}
|
|
100
|
+
insertTrigger(e, t, r, i) {
|
|
101
|
+
return this._immediate.insertTrigger(e, t, r, i).run();
|
|
102
|
+
}
|
|
103
|
+
removeTrigger(e) {
|
|
104
|
+
return this._immediate.removeTrigger(e).run();
|
|
105
|
+
}
|
|
106
|
+
insertRpc(e, t) {
|
|
107
|
+
return this._immediate.insertRpc(e, t).run();
|
|
108
|
+
}
|
|
109
|
+
removeRpc(e) {
|
|
110
|
+
return this._immediate.removeRpc(e).run();
|
|
111
|
+
}
|
|
112
|
+
on(e, t) {
|
|
113
|
+
return this.qyCache.on(e, t);
|
|
114
|
+
}
|
|
115
|
+
callRpc(e, t, r) {
|
|
116
|
+
return this.qyCache.callRpc(e, t, r);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Object.assign(module.exports, {
|
|
121
|
+
QyDB: QyDB
|
|
122
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
let writerConfig = {
|
|
2
|
+
append: !1,
|
|
3
|
+
retryIntervalFactor: 2,
|
|
4
|
+
maxRetryInterval: 60,
|
|
5
|
+
emitSaveEvent: !1,
|
|
6
|
+
maxFileSize: 1 / 0
|
|
7
|
+
}, Default_Options = {
|
|
8
|
+
QyBaseWriter: writerConfig,
|
|
9
|
+
QyBinWriter: writerConfig,
|
|
10
|
+
QyBatch: {
|
|
11
|
+
fileLogLevel: "delta",
|
|
12
|
+
maxHistoryCmdObjCount: 100
|
|
13
|
+
},
|
|
14
|
+
QyKVData: {
|
|
15
|
+
append: !0,
|
|
16
|
+
emitSaveEvent: !0,
|
|
17
|
+
saveSnapshotAtStop: !0,
|
|
18
|
+
autoRepairAclFile: !0,
|
|
19
|
+
snapshotMaxChangeCount: 1e6,
|
|
20
|
+
compactSnapshotsInterval: 6e4,
|
|
21
|
+
bgLoadPosMaps: !0,
|
|
22
|
+
unloadMemInterval: 12e4,
|
|
23
|
+
maxFileCountToUnload: 1e5
|
|
24
|
+
},
|
|
25
|
+
QyCache: {
|
|
26
|
+
dumpStructureAtStart: !1,
|
|
27
|
+
queryAutoCreateIndex: !0,
|
|
28
|
+
preloadFoldersAtStart: !1
|
|
29
|
+
},
|
|
30
|
+
QyFileLogger: {
|
|
31
|
+
clearLogAtStart: !1
|
|
32
|
+
},
|
|
33
|
+
QySaver: {
|
|
34
|
+
retryTimes: 10,
|
|
35
|
+
retryIntervalFactor: 2,
|
|
36
|
+
maxRetryInterval: 60
|
|
37
|
+
},
|
|
38
|
+
QyQueue: {
|
|
39
|
+
maxLenBeforeRecycle: 1e3
|
|
40
|
+
},
|
|
41
|
+
QySnapshots: {
|
|
42
|
+
pMOutdatedPercent: 30,
|
|
43
|
+
minSnapshotKeyCount: 3e3
|
|
44
|
+
},
|
|
45
|
+
QyKVDataCleaner_Worker: {
|
|
46
|
+
compressRedundantFile: !1
|
|
47
|
+
},
|
|
48
|
+
QySnapshotSaver_Worker: {
|
|
49
|
+
maxInMemSnapshotCount: 3
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function getDefaultOptions(e) {
|
|
54
|
+
return e && Default_Options[e] || void 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Object.assign(module.exports, {
|
|
58
|
+
getDefaultOptions: getDefaultOptions
|
|
59
|
+
});
|