json-fs-query 3.2.0 → 3.3.1
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 +265 -17
- package/browser/jsonFsQuery.js +2274 -305
- package/browser/jsonFsQuery.min.js +1 -1
- package/dist/data/introspect/alter.d.ts +12 -0
- package/dist/data/introspect/alter.js +304 -0
- package/dist/data/introspect/alter.min.js +1 -0
- package/dist/data/introspect/create.d.ts +10 -0
- package/dist/data/introspect/create.js +8 -2
- package/dist/data/introspect/create.min.js +1 -1
- package/dist/data/introspect/drop.js +2 -0
- package/dist/data/introspect/drop.min.js +1 -1
- package/dist/data/introspect/formatDatabase.d.ts +17 -0
- package/dist/data/introspect/formatDatabase.js +56 -0
- package/dist/data/introspect/formatDatabase.min.js +1 -0
- package/dist/data/introspect/index.d.ts +9 -0
- package/dist/data/introspect/index.js +18 -5
- package/dist/data/introspect/index.min.js +1 -1
- package/dist/data/introspect/packDatabase.d.ts +27 -0
- package/dist/data/introspect/packDatabase.js +113 -0
- package/dist/data/introspect/packDatabase.min.js +1 -0
- package/dist/data/queries/databaseStatements.d.ts +31 -0
- package/dist/data/queries/databaseStatements.js +97 -0
- package/dist/data/queries/databaseStatements.min.js +1 -0
- package/dist/data/queries/deleteEntity.js +6 -1
- package/dist/data/queries/deleteEntity.min.js +1 -1
- package/dist/data/queries/insertEntity.d.ts +8 -0
- package/dist/data/queries/insertEntity.js +342 -33
- package/dist/data/queries/insertEntity.min.js +1 -1
- package/dist/data/queries/query.d.ts +2 -1
- package/dist/data/queries/query.js +5 -2
- package/dist/data/queries/query.min.js +1 -1
- package/dist/data/queries/selectFields.d.ts +5 -4
- package/dist/data/queries/selectFields.js +25 -11
- package/dist/data/queries/selectFields.min.js +1 -1
- package/dist/data/queries/updateEntity.js +39 -5
- package/dist/data/queries/updateEntity.min.js +1 -1
- package/dist/data/storage/databases.d.ts +32 -0
- package/dist/data/storage/databases.js +93 -0
- package/dist/data/storage/databases.min.js +1 -0
- package/dist/data/storage/fileExists.d.ts +2 -1
- package/dist/data/storage/fileExists.js +9 -2
- package/dist/data/storage/fileExists.min.js +1 -1
- package/dist/data/storage/index.d.ts +5 -2
- package/dist/data/storage/index.js +64 -1
- package/dist/data/storage/index.min.js +1 -1
- package/dist/data/storage/listFiles.d.ts +8 -0
- package/dist/data/storage/listFiles.js +52 -0
- package/dist/data/storage/listFiles.min.js +1 -0
- package/dist/data/storage/makeDirectory.d.ts +2 -1
- package/dist/data/storage/makeDirectory.js +8 -2
- package/dist/data/storage/makeDirectory.min.js +1 -1
- package/dist/data/storage/readJson.d.ts +9 -1
- package/dist/data/storage/readJson.js +20 -7
- package/dist/data/storage/readJson.min.js +1 -1
- package/dist/data/storage/removeDirectory.d.ts +3 -1
- package/dist/data/storage/removeDirectory.js +7 -1
- package/dist/data/storage/removeDirectory.min.js +1 -1
- package/dist/data/storage/removeFile.d.ts +2 -1
- package/dist/data/storage/removeFile.js +10 -1
- package/dist/data/storage/removeFile.min.js +1 -1
- package/dist/data/storage/storagePath.js +1 -1
- package/dist/data/storage/storagePath.min.js +1 -1
- package/dist/data/storage/writeJson.d.ts +12 -3
- package/dist/data/storage/writeJson.js +21 -7
- package/dist/data/storage/writeJson.min.js +1 -1
- package/dist/data/storage/writeSet.d.ts +64 -0
- package/dist/data/storage/writeSet.js +306 -0
- package/dist/data/storage/writeSet.min.js +1 -0
- package/dist/data/utilities/config.d.ts +37 -0
- package/dist/data/utilities/config.js +77 -5
- package/dist/data/utilities/config.min.js +1 -1
- package/dist/data/utilities/databaseLock.d.ts +5 -0
- package/dist/data/utilities/databaseLock.js +15 -3
- package/dist/data/utilities/databaseLock.min.js +1 -1
- package/dist/data/utilities/getConditionIndexedList.js +3 -4
- package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
- package/dist/data/utilities/indexBuffer.d.ts +35 -0
- package/dist/data/utilities/indexBuffer.js +139 -0
- package/dist/data/utilities/indexBuffer.min.js +1 -0
- package/dist/data/utilities/joinBases.js +2 -10
- package/dist/data/utilities/joinBases.min.js +1 -1
- package/dist/data/utilities/knownFields.d.ts +26 -0
- package/dist/data/utilities/knownFields.js +128 -0
- package/dist/data/utilities/knownFields.min.js +1 -0
- package/dist/data/utilities/packedTable.d.ts +34 -0
- package/dist/data/utilities/packedTable.js +60 -0
- package/dist/data/utilities/packedTable.min.js +1 -0
- package/dist/data/utilities/parsers/findInsertValues.d.ts +3 -3
- package/dist/data/utilities/parsers/findInsertValues.js +28 -12
- package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
- package/dist/data/utilities/parsers/maskStrings.js +11 -2
- package/dist/data/utilities/parsers/maskStrings.min.js +1 -1
- package/dist/data/utilities/parsers/parseAlter.d.ts +33 -0
- package/dist/data/utilities/parsers/parseAlter.js +84 -0
- package/dist/data/utilities/parsers/parseAlter.min.js +1 -0
- package/dist/data/utilities/parsers/parseCreate.d.ts +14 -0
- package/dist/data/utilities/parsers/parseCreate.js +13 -5
- package/dist/data/utilities/parsers/parseCreate.min.js +1 -1
- package/dist/data/utilities/parsers/parseDatabaseStatement.d.ts +17 -0
- package/dist/data/utilities/parsers/parseDatabaseStatement.js +82 -0
- package/dist/data/utilities/parsers/parseDatabaseStatement.min.js +1 -0
- package/dist/data/utilities/parsers/parseQuery.d.ts +3 -0
- package/dist/data/utilities/parsers/parseQuery.js +24 -0
- package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
- package/dist/data/utilities/parsers/startsQuery.js +1 -1
- package/dist/data/utilities/parsers/startsQuery.min.js +1 -1
- package/dist/data/utilities/reconcileJoin.d.ts +12 -0
- package/dist/data/utilities/reconcileJoin.js +30 -10
- package/dist/data/utilities/reconcileJoin.min.js +1 -1
- package/dist/data/utilities/retrieveFiles.d.ts +15 -0
- package/dist/data/utilities/retrieveFiles.js +48 -0
- package/dist/data/utilities/retrieveFiles.min.js +1 -0
- package/dist/data/utilities/retrieveRecord.d.ts +6 -0
- package/dist/data/utilities/retrieveRecord.js +24 -1
- package/dist/data/utilities/retrieveRecord.min.js +1 -1
- package/dist/data/utilities/retrieveRecords.d.ts +22 -0
- package/dist/data/utilities/retrieveRecords.js +60 -10
- package/dist/data/utilities/retrieveRecords.min.js +1 -1
- package/dist/data/utilities/runQuery.js +27 -2
- package/dist/data/utilities/runQuery.min.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +24 -0
- package/dist/index.min.js +1 -1
- package/package.json +8 -4
|
@@ -7,12 +7,18 @@ exports.removeDirectory = void 0;
|
|
|
7
7
|
var _storagePath = require("./storagePath");
|
|
8
8
|
var _nodeFiles = require("./nodeFiles");
|
|
9
9
|
var _readCache = require("./readCache");
|
|
10
|
+
var _writeSet = require("./writeSet");
|
|
10
11
|
/**
|
|
11
|
-
* Delete a folder of the database and everything in it; a folder that doesn't exist is left alone.
|
|
12
|
+
* Delete a folder of the database and everything in it; a folder that doesn't exist is left alone. During a statement
|
|
13
|
+
* it's removed with the statement's other changes (see withWriteSet), and reads in the statement already find
|
|
14
|
+
* everything in it gone. Node only.
|
|
12
15
|
* @param path - A path inside the database, such as `__indexes/users`.
|
|
13
16
|
*/
|
|
14
17
|
const removeDirectory = async path => {
|
|
15
18
|
const location = (0, _storagePath.storagePath)(path);
|
|
19
|
+
if ((0, _writeSet.stageRemoveDirectory)(location)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
16
22
|
// Forgotten before and after: a read that starts while rm runs would otherwise keep a removed file's old text
|
|
17
23
|
(0, _readCache.cacheRemove)(location, true);
|
|
18
24
|
await (0, _nodeFiles.nodeFiles)().rm(location, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeDirectory=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache");const removeDirectory=async e=>{const r=(0,_storagePath.storagePath)(e);(0,_readCache.cacheRemove)(r,!0),await(0,_nodeFiles.nodeFiles)().rm(r,{recursive:!0,force:!0}),(0,_readCache.cacheRemove)(r,!0)};exports.removeDirectory=removeDirectory;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeDirectory=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache"),_writeSet=require("./writeSet");const removeDirectory=async e=>{const r=(0,_storagePath.storagePath)(e);(0,_writeSet.stageRemoveDirectory)(r)||((0,_readCache.cacheRemove)(r,!0),await(0,_nodeFiles.nodeFiles)().rm(r,{recursive:!0,force:!0}),(0,_readCache.cacheRemove)(r,!0))};exports.removeDirectory=removeDirectory;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Delete one file of the database.
|
|
2
|
+
* Delete one file of the database. During a statement the delete waits in its write set until the statement succeeds
|
|
3
|
+
* (see withWriteSet), and reads in the statement already find the file gone. Node only.
|
|
3
4
|
* @param path - A path inside the database, such as `users/1.json`.
|
|
4
5
|
* @throws {Error} When the file doesn't exist.
|
|
5
6
|
*/
|
|
@@ -7,13 +7,22 @@ exports.removeFile = void 0;
|
|
|
7
7
|
var _storagePath = require("./storagePath");
|
|
8
8
|
var _nodeFiles = require("./nodeFiles");
|
|
9
9
|
var _readCache = require("./readCache");
|
|
10
|
+
var _writeSet = require("./writeSet");
|
|
10
11
|
/**
|
|
11
|
-
* Delete one file of the database.
|
|
12
|
+
* Delete one file of the database. During a statement the delete waits in its write set until the statement succeeds
|
|
13
|
+
* (see withWriteSet), and reads in the statement already find the file gone. Node only.
|
|
12
14
|
* @param path - A path inside the database, such as `users/1.json`.
|
|
13
15
|
* @throws {Error} When the file doesn't exist.
|
|
14
16
|
*/
|
|
15
17
|
const removeFile = async path => {
|
|
16
18
|
const location = (0, _storagePath.storagePath)(path);
|
|
19
|
+
const pending = (0, _writeSet.pendingFile)(location);
|
|
20
|
+
if (pending === null || pending === undefined && !require('fs').existsSync(location)) {
|
|
21
|
+
throw new Error(`ENOENT: no such file or directory, rm '${location}'`);
|
|
22
|
+
}
|
|
23
|
+
if ((0, _writeSet.stageRemove)(location)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
17
26
|
// Forgotten before and after: a read that starts while rm runs would otherwise keep the file's old text
|
|
18
27
|
(0, _readCache.cacheRemove)(location);
|
|
19
28
|
await (0, _nodeFiles.nodeFiles)().rm(location);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeFile=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache");const removeFile=async e=>{const r=(0,_storagePath.storagePath)(e);(0,_readCache.cacheRemove)(r),await(0,_nodeFiles.nodeFiles)().rm(r),(0,_readCache.cacheRemove)(r)};exports.removeFile=removeFile;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeFile=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache"),_writeSet=require("./writeSet");const removeFile=async e=>{const r=(0,_storagePath.storagePath)(e),t=(0,_writeSet.pendingFile)(r);if(null===t||void 0===t&&!require("fs").existsSync(r))throw new Error(`ENOENT: no such file or directory, rm '${r}'`);(0,_writeSet.stageRemove)(r)||((0,_readCache.cacheRemove)(r),await(0,_nodeFiles.nodeFiles)().rm(r),(0,_readCache.cacheRemove)(r))};exports.removeFile=removeFile;
|
|
@@ -20,6 +20,6 @@ function _interopRequireWildcard(t, r) { if (!r && t && t.__esModule) return t;
|
|
|
20
20
|
*/
|
|
21
21
|
const storagePath = (path = '') => {
|
|
22
22
|
const relativePath = jsEnv.isBrowser ? (0, _config.getSetting)('relativePath', '') : '';
|
|
23
|
-
return `${relativePath}${(0, _config.
|
|
23
|
+
return `${relativePath}${(0, _config.activeDatabasePath)()}${path}`;
|
|
24
24
|
};
|
|
25
25
|
exports.storagePath = storagePath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.storagePath=void 0;var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("../utilities/config");function _interopRequireWildcard(t,r){if(!r&&t&&t.__esModule)return t;var a,
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.storagePath=void 0;var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("../utilities/config");function _interopRequireWildcard(t,r){if(!r&&t&&t.__esModule)return t;var o,a,i=Object.defineProperty,s={__proto__:null,default:t};if(Object(t)!==t)return s;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(t))return e.get(t);e.set(t,s)}for(a in t)"default"!==a&&{}.hasOwnProperty.call(t,a)&&((o=i&&Object.getOwnPropertyDescriptor(t,a))&&(o.get||o.set)?i(s,a,o):s[a]=t[a]);return s}const storagePath=(e="")=>`${jsEnv.isBrowser?(0,_config.getSetting)("relativePath",""):""}${(0,_config.activeDatabasePath)()}${e}`;exports.storagePath=storagePath;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* The text a file of the database holds for `content`: compact JSON, or indented by 2 spaces for `pretty`.
|
|
3
|
+
* @param content - Anything JSON.stringify accepts.
|
|
4
|
+
* @param format - Defaults to the configured format (see configure).
|
|
5
|
+
*/
|
|
6
|
+
export declare const jsonText: (content: any, format?: "compact" | "pretty") => string;
|
|
7
|
+
/**
|
|
8
|
+
* Write `content` to one file of the database as JSON in the configured format (see jsonText), replacing the file if it
|
|
9
|
+
* exists. Its folder must already exist (see makeDirectory). The file is replaced whole or not at all (see
|
|
10
|
+
* writeAtomically). During a statement the write waits in its write set until the statement succeeds (see
|
|
11
|
+
* withWriteSet). Node only.
|
|
4
12
|
* @param path - A path inside the database, such as `users.json`.
|
|
5
13
|
* @param content - Anything JSON.stringify accepts.
|
|
14
|
+
* @param format - Defaults to the configured format (see configure).
|
|
6
15
|
*/
|
|
7
|
-
export declare const writeJson: (path: string, content: any) => Promise<void>;
|
|
16
|
+
export declare const writeJson: (path: string, content: any, format?: "compact" | "pretty") => Promise<void>;
|
|
8
17
|
//# sourceMappingURL=writeJson.d.ts.map
|
|
@@ -3,21 +3,35 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.writeJson = void 0;
|
|
6
|
+
exports.writeJson = exports.jsonText = void 0;
|
|
7
7
|
require("core-js/modules/es.json.stringify.js");
|
|
8
8
|
var _storagePath = require("./storagePath");
|
|
9
|
-
var _nodeFiles = require("./nodeFiles");
|
|
10
9
|
var _readCache = require("./readCache");
|
|
10
|
+
var _writeSet = require("./writeSet");
|
|
11
|
+
var _config = require("../utilities/config");
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* The text a file of the database holds for `content`: compact JSON, or indented by 2 spaces for `pretty`.
|
|
14
|
+
* @param content - Anything JSON.stringify accepts.
|
|
15
|
+
* @param format - Defaults to the configured format (see configure).
|
|
16
|
+
*/
|
|
17
|
+
const jsonText = (content, format = (0, _config.getSetting)('format', 'compact')) => format === 'pretty' ? JSON.stringify(content, null, 2) : JSON.stringify(content);
|
|
18
|
+
/**
|
|
19
|
+
* Write `content` to one file of the database as JSON in the configured format (see jsonText), replacing the file if it
|
|
20
|
+
* exists. Its folder must already exist (see makeDirectory). The file is replaced whole or not at all (see
|
|
21
|
+
* writeAtomically). During a statement the write waits in its write set until the statement succeeds (see
|
|
22
|
+
* withWriteSet). Node only.
|
|
14
23
|
* @param path - A path inside the database, such as `users.json`.
|
|
15
24
|
* @param content - Anything JSON.stringify accepts.
|
|
25
|
+
* @param format - Defaults to the configured format (see configure).
|
|
16
26
|
*/
|
|
17
|
-
|
|
27
|
+
exports.jsonText = jsonText;
|
|
28
|
+
const writeJson = async (path, content, format) => {
|
|
18
29
|
const location = (0, _storagePath.storagePath)(path);
|
|
19
|
-
const text =
|
|
20
|
-
|
|
30
|
+
const text = jsonText(content, format);
|
|
31
|
+
if ((0, _writeSet.stageWrite)(location, text)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
await (0, _writeSet.writeAtomically)(location, text);
|
|
21
35
|
(0, _readCache.cacheWrite)(location, text);
|
|
22
36
|
};
|
|
23
37
|
exports.writeJson = writeJson;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.writeJson=void 0,require("core-js/modules/es.json.stringify.js");var _storagePath=require("./storagePath"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.writeJson=exports.jsonText=void 0,require("core-js/modules/es.json.stringify.js");var _storagePath=require("./storagePath"),_readCache=require("./readCache"),_writeSet=require("./writeSet"),_config=require("../utilities/config");const jsonText=(e,t=(0,_config.getSetting)("format","compact"))=>"pretty"===t?JSON.stringify(e,null,2):JSON.stringify(e);exports.jsonText=jsonText;const writeJson=async(e,t,r)=>{const s=(0,_storagePath.storagePath)(e),i=jsonText(t,r);(0,_writeSet.stageWrite)(s,i)||(await(0,_writeSet.writeAtomically)(s,i),(0,_readCache.cacheWrite)(s,i))};exports.writeJson=writeJson;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write `text` to `location` so that the file is always either its old or its new content, never half of one: the
|
|
3
|
+
* text goes to a temporary file next to it, which then replaces it (a rename is atomic within one folder). That holds
|
|
4
|
+
* when the process stops part way (a crash, a kill); there's no fsync, so after a power cut the file system may still
|
|
5
|
+
* lose a recent write. When the write or rename fails, the temporary file is removed and the original error thrown.
|
|
6
|
+
* @param location
|
|
7
|
+
* @param text
|
|
8
|
+
*/
|
|
9
|
+
export declare const writeAtomically: (location: string, text: string) => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Run one statement's `task` with a write set for the configured database: its writes and deletes are collected in
|
|
12
|
+
* memory, and reads during the task see them (see pendingFile). When the task finishes, everything it changed is put in
|
|
13
|
+
* storage at once, each file written once however many times the task changed it. When it throws, nothing it changed
|
|
14
|
+
* reaches storage: a multi-row insert or update whose third row fails leaves the first two unwritten too.
|
|
15
|
+
*
|
|
16
|
+
* A task inside another (a public call made from inside a statement) joins the outer write set. Node only: in a
|
|
17
|
+
* browser nothing can be written, so the task just runs.
|
|
18
|
+
* @param task
|
|
19
|
+
*/
|
|
20
|
+
export declare const withWriteSet: <T>(task: () => Promise<T>) => Promise<T>;
|
|
21
|
+
/**
|
|
22
|
+
* What the running statement has done to the file at `location`: its pending text, `null` if the statement deleted it
|
|
23
|
+
* (or a folder it was in), or `undefined` when the statement hasn't touched it (or no statement is running).
|
|
24
|
+
* @param location - The file's full location (see storagePath).
|
|
25
|
+
*/
|
|
26
|
+
export declare const pendingFile: (location: string) => string | null | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the file or folder at `location` exists as far as the running statement knows: true for a file it wrote, a
|
|
29
|
+
* folder it made, or a folder holding something it wrote or made; false for a file it deleted or anything in a folder
|
|
30
|
+
* it removed; `undefined` when the statement hasn't touched it (or no statement is running), so storage decides.
|
|
31
|
+
* @param location - The full location (see storagePath).
|
|
32
|
+
*/
|
|
33
|
+
export declare const pendingExists: (location: string) => boolean | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* The files under `folder` as the running statement sees them: `onDisk` (full locations) without what it deleted or
|
|
36
|
+
* removed, plus what it wrote there. `onDisk` as it is when no statement is running.
|
|
37
|
+
* @param folder - The folder's full location (see storagePath).
|
|
38
|
+
* @param onDisk - The full locations of the files under it in storage.
|
|
39
|
+
*/
|
|
40
|
+
export declare const pendingListing: (folder: string, onDisk: string[]) => string[];
|
|
41
|
+
/**
|
|
42
|
+
* Keep `text` as the new content of `location` in the running statement's write set. False when no statement is
|
|
43
|
+
* running, so the caller writes to storage itself.
|
|
44
|
+
* @param location
|
|
45
|
+
* @param text
|
|
46
|
+
*/
|
|
47
|
+
export declare const stageWrite: (location: string, text: string) => boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Mark `location` deleted in the running statement's write set. False when no statement is running.
|
|
50
|
+
* @param location
|
|
51
|
+
*/
|
|
52
|
+
export declare const stageRemove: (location: string) => boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Note a folder to create in the running statement's write set. False when no statement is running.
|
|
55
|
+
* @param location
|
|
56
|
+
*/
|
|
57
|
+
export declare const stageMakeDirectory: (location: string) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Mark a folder and everything in it removed in the running statement's write set: what the statement wrote or
|
|
60
|
+
* created inside it so far is dropped with it. False when no statement is running.
|
|
61
|
+
* @param location
|
|
62
|
+
*/
|
|
63
|
+
export declare const stageRemoveDirectory: (location: string) => boolean;
|
|
64
|
+
//# sourceMappingURL=writeSet.d.ts.map
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.writeAtomically = exports.withWriteSet = exports.stageWrite = exports.stageRemoveDirectory = exports.stageRemove = exports.stageMakeDirectory = exports.pendingListing = exports.pendingFile = exports.pendingExists = void 0;
|
|
8
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
+
require("core-js/modules/esnext.iterator.filter.js");
|
|
10
|
+
require("core-js/modules/esnext.map.delete-all.js");
|
|
11
|
+
require("core-js/modules/esnext.map.every.js");
|
|
12
|
+
require("core-js/modules/esnext.map.filter.js");
|
|
13
|
+
require("core-js/modules/esnext.map.find.js");
|
|
14
|
+
require("core-js/modules/esnext.map.find-key.js");
|
|
15
|
+
require("core-js/modules/esnext.map.includes.js");
|
|
16
|
+
require("core-js/modules/esnext.map.key-of.js");
|
|
17
|
+
require("core-js/modules/esnext.map.map-keys.js");
|
|
18
|
+
require("core-js/modules/esnext.map.map-values.js");
|
|
19
|
+
require("core-js/modules/esnext.map.merge.js");
|
|
20
|
+
require("core-js/modules/esnext.map.reduce.js");
|
|
21
|
+
require("core-js/modules/esnext.map.some.js");
|
|
22
|
+
require("core-js/modules/esnext.map.update.js");
|
|
23
|
+
require("core-js/modules/esnext.set.add-all.js");
|
|
24
|
+
require("core-js/modules/esnext.set.delete-all.js");
|
|
25
|
+
require("core-js/modules/esnext.set.difference.js");
|
|
26
|
+
require("core-js/modules/esnext.set.every.js");
|
|
27
|
+
require("core-js/modules/esnext.set.filter.js");
|
|
28
|
+
require("core-js/modules/esnext.set.find.js");
|
|
29
|
+
require("core-js/modules/esnext.set.intersection.js");
|
|
30
|
+
require("core-js/modules/esnext.set.is-disjoint-from.js");
|
|
31
|
+
require("core-js/modules/esnext.set.is-subset-of.js");
|
|
32
|
+
require("core-js/modules/esnext.set.is-superset-of.js");
|
|
33
|
+
require("core-js/modules/esnext.set.join.js");
|
|
34
|
+
require("core-js/modules/esnext.set.map.js");
|
|
35
|
+
require("core-js/modules/esnext.set.reduce.js");
|
|
36
|
+
require("core-js/modules/esnext.set.some.js");
|
|
37
|
+
require("core-js/modules/esnext.set.symmetric-difference.js");
|
|
38
|
+
require("core-js/modules/esnext.set.union.js");
|
|
39
|
+
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
40
|
+
var _storagePath = require("./storagePath");
|
|
41
|
+
var _nodeFiles = require("./nodeFiles");
|
|
42
|
+
var _readCache = require("./readCache");
|
|
43
|
+
var e;
|
|
44
|
+
function _interopRequireWildcard(t, r) { if (!r && t && t.__esModule) return t; var n, a, o = Object.defineProperty, f = { __proto__: null, default: t }; if (Object(t) !== t) return f; if (e || "function" != typeof WeakMap || (e = new WeakMap()), e) { if (e.has(t)) return e.get(t); e.set(t, f); } for (a in t) "default" !== a && {}.hasOwnProperty.call(t, a) && ((n = o && Object.getOwnPropertyDescriptor(t, a)) && (n.get || n.set) ? o(f, a, n) : f[a] = t[a]); return f; }
|
|
45
|
+
const writeSets = new Map();
|
|
46
|
+
/**
|
|
47
|
+
* The write set of the database configured now (by its location, see storagePath), if a statement on it is running.
|
|
48
|
+
*/
|
|
49
|
+
const currentWriteSet = () => writeSets.get((0, _storagePath.storagePath)());
|
|
50
|
+
const folderPrefix = location => location.endsWith('/') ? location : `${location}/`;
|
|
51
|
+
/**
|
|
52
|
+
* Whether `location` is inside one of the folders `folders` (or is one of them).
|
|
53
|
+
* @param location
|
|
54
|
+
* @param folders
|
|
55
|
+
*/
|
|
56
|
+
const insideAny = (location, folders) => {
|
|
57
|
+
for (const folder of folders) {
|
|
58
|
+
if (location === folder || location.startsWith(folderPrefix(folder))) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Write `text` to `location` so that the file is always either its old or its new content, never half of one: the
|
|
66
|
+
* text goes to a temporary file next to it, which then replaces it (a rename is atomic within one folder). That holds
|
|
67
|
+
* when the process stops part way (a crash, a kill); there's no fsync, so after a power cut the file system may still
|
|
68
|
+
* lose a recent write. When the write or rename fails, the temporary file is removed and the original error thrown.
|
|
69
|
+
* @param location
|
|
70
|
+
* @param text
|
|
71
|
+
*/
|
|
72
|
+
const writeAtomically = async (location, text) => {
|
|
73
|
+
const temporary = `${location}.${crypto.randomUUID()}.tmp`;
|
|
74
|
+
const files = (0, _nodeFiles.nodeFiles)();
|
|
75
|
+
try {
|
|
76
|
+
await files.writeFile(temporary, text);
|
|
77
|
+
await files.rename(temporary, location);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// Cleaning up is best effort: its own failure must not hide why the write failed
|
|
80
|
+
await files.rm(temporary, {
|
|
81
|
+
force: true
|
|
82
|
+
}).catch(() => undefined);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Remove a folder from storage and from the read cache.
|
|
88
|
+
* @param location
|
|
89
|
+
*/
|
|
90
|
+
exports.writeAtomically = writeAtomically;
|
|
91
|
+
const removeFolder = async location => {
|
|
92
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
93
|
+
await (0, _nodeFiles.nodeFiles)().rm(location, {
|
|
94
|
+
recursive: true,
|
|
95
|
+
force: true
|
|
96
|
+
});
|
|
97
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Put a write set's changes in storage, in an order where a stop part way leaves at worst an unlisted file or folder
|
|
101
|
+
* behind, never a record file or index that lists something missing:
|
|
102
|
+
* - folders the statement removed and then wrote into again (none today), so the new content survives;
|
|
103
|
+
* - new folders;
|
|
104
|
+
* - every written file once, in the order each was last written (a record's entry list and indexes come after the
|
|
105
|
+
* entries they list);
|
|
106
|
+
* - deleted files (a delete has already rewritten the record file and indexes; `drop` removes its record file here);
|
|
107
|
+
* - the other removed folders (`drop`'s entries and indexes, after its record file is gone).
|
|
108
|
+
* Each change also goes into the read cache, which holds what's in storage.
|
|
109
|
+
* @param writeSet
|
|
110
|
+
*/
|
|
111
|
+
const commit = async writeSet => {
|
|
112
|
+
const files = (0, _nodeFiles.nodeFiles)();
|
|
113
|
+
const writtenInto = folder => {
|
|
114
|
+
const prefix = folderPrefix(folder);
|
|
115
|
+
return [...writeSet.madeFolders].some(made => made === folder || made.startsWith(prefix)) || [...writeSet.files].some(([location, text]) => text !== null && location.startsWith(prefix));
|
|
116
|
+
};
|
|
117
|
+
const removedFolders = [...writeSet.removedFolders];
|
|
118
|
+
for (const folder of removedFolders.filter(writtenInto)) {
|
|
119
|
+
await removeFolder(folder);
|
|
120
|
+
}
|
|
121
|
+
for (const folder of writeSet.madeFolders) {
|
|
122
|
+
await files.mkdir(folder, {
|
|
123
|
+
recursive: true
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
for (const [location, text] of writeSet.files) {
|
|
127
|
+
if (text !== null) {
|
|
128
|
+
await writeAtomically(location, text);
|
|
129
|
+
(0, _readCache.cacheWrite)(location, text);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
for (const [location, text] of writeSet.files) {
|
|
133
|
+
if (text === null) {
|
|
134
|
+
(0, _readCache.cacheRemove)(location);
|
|
135
|
+
await files.rm(location, {
|
|
136
|
+
force: true
|
|
137
|
+
});
|
|
138
|
+
(0, _readCache.cacheRemove)(location);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const folder of removedFolders.filter(folder => !writtenInto(folder))) {
|
|
142
|
+
await removeFolder(folder);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Run one statement's `task` with a write set for the configured database: its writes and deletes are collected in
|
|
147
|
+
* memory, and reads during the task see them (see pendingFile). When the task finishes, everything it changed is put in
|
|
148
|
+
* storage at once, each file written once however many times the task changed it. When it throws, nothing it changed
|
|
149
|
+
* reaches storage: a multi-row insert or update whose third row fails leaves the first two unwritten too.
|
|
150
|
+
*
|
|
151
|
+
* A task inside another (a public call made from inside a statement) joins the outer write set. Node only: in a
|
|
152
|
+
* browser nothing can be written, so the task just runs.
|
|
153
|
+
* @param task
|
|
154
|
+
*/
|
|
155
|
+
const withWriteSet = async task => {
|
|
156
|
+
const database = (0, _storagePath.storagePath)();
|
|
157
|
+
if (!jsEnv.isNode || writeSets.has(database)) {
|
|
158
|
+
return task();
|
|
159
|
+
}
|
|
160
|
+
const writeSet = {
|
|
161
|
+
files: new Map(),
|
|
162
|
+
madeFolders: new Set(),
|
|
163
|
+
removedFolders: new Set()
|
|
164
|
+
};
|
|
165
|
+
writeSets.set(database, writeSet);
|
|
166
|
+
let result;
|
|
167
|
+
try {
|
|
168
|
+
result = await task();
|
|
169
|
+
} finally {
|
|
170
|
+
writeSets.delete(database);
|
|
171
|
+
}
|
|
172
|
+
await commit(writeSet);
|
|
173
|
+
return result;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* What the running statement has done to the file at `location`: its pending text, `null` if the statement deleted it
|
|
177
|
+
* (or a folder it was in), or `undefined` when the statement hasn't touched it (or no statement is running).
|
|
178
|
+
* @param location - The file's full location (see storagePath).
|
|
179
|
+
*/
|
|
180
|
+
exports.withWriteSet = withWriteSet;
|
|
181
|
+
const pendingFile = location => {
|
|
182
|
+
const writeSet = currentWriteSet();
|
|
183
|
+
if (!writeSet) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
if (writeSet.files.has(location)) {
|
|
187
|
+
return writeSet.files.get(location);
|
|
188
|
+
}
|
|
189
|
+
return insideAny(location, writeSet.removedFolders) ? null : undefined;
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Whether the file or folder at `location` exists as far as the running statement knows: true for a file it wrote, a
|
|
193
|
+
* folder it made, or a folder holding something it wrote or made; false for a file it deleted or anything in a folder
|
|
194
|
+
* it removed; `undefined` when the statement hasn't touched it (or no statement is running), so storage decides.
|
|
195
|
+
* @param location - The full location (see storagePath).
|
|
196
|
+
*/
|
|
197
|
+
exports.pendingFile = pendingFile;
|
|
198
|
+
const pendingExists = location => {
|
|
199
|
+
const writeSet = currentWriteSet();
|
|
200
|
+
if (!writeSet) {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
if (writeSet.files.has(location)) {
|
|
204
|
+
return writeSet.files.get(location) !== null;
|
|
205
|
+
}
|
|
206
|
+
const prefix = folderPrefix(location);
|
|
207
|
+
const madeInside = path => path === location || path.startsWith(prefix);
|
|
208
|
+
if ([...writeSet.madeFolders].some(madeInside) || [...writeSet.files].some(([path, text]) => text !== null && path.startsWith(prefix))) {
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
return insideAny(location, writeSet.removedFolders) ? false : undefined;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* The files under `folder` as the running statement sees them: `onDisk` (full locations) without what it deleted or
|
|
215
|
+
* removed, plus what it wrote there. `onDisk` as it is when no statement is running.
|
|
216
|
+
* @param folder - The folder's full location (see storagePath).
|
|
217
|
+
* @param onDisk - The full locations of the files under it in storage.
|
|
218
|
+
*/
|
|
219
|
+
exports.pendingExists = pendingExists;
|
|
220
|
+
const pendingListing = (folder, onDisk) => {
|
|
221
|
+
const writeSet = currentWriteSet();
|
|
222
|
+
if (!writeSet) {
|
|
223
|
+
return onDisk;
|
|
224
|
+
}
|
|
225
|
+
const prefix = folderPrefix(folder);
|
|
226
|
+
const listed = new Set(onDisk.filter(location => !insideAny(location, writeSet.removedFolders)));
|
|
227
|
+
for (const [location, text] of writeSet.files) {
|
|
228
|
+
if (location.startsWith(prefix)) {
|
|
229
|
+
if (text === null) {
|
|
230
|
+
listed.delete(location);
|
|
231
|
+
} else {
|
|
232
|
+
listed.add(location);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return [...listed];
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Keep `text` as the new content of `location` in the running statement's write set. False when no statement is
|
|
240
|
+
* running, so the caller writes to storage itself.
|
|
241
|
+
* @param location
|
|
242
|
+
* @param text
|
|
243
|
+
*/
|
|
244
|
+
exports.pendingListing = pendingListing;
|
|
245
|
+
const stageWrite = (location, text) => {
|
|
246
|
+
const writeSet = currentWriteSet();
|
|
247
|
+
if (!writeSet) {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
// Moved to the end, so files are written in the order they were last changed
|
|
251
|
+
writeSet.files.delete(location);
|
|
252
|
+
writeSet.files.set(location, text);
|
|
253
|
+
return true;
|
|
254
|
+
};
|
|
255
|
+
/**
|
|
256
|
+
* Mark `location` deleted in the running statement's write set. False when no statement is running.
|
|
257
|
+
* @param location
|
|
258
|
+
*/
|
|
259
|
+
exports.stageWrite = stageWrite;
|
|
260
|
+
const stageRemove = location => {
|
|
261
|
+
const writeSet = currentWriteSet();
|
|
262
|
+
if (!writeSet) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
writeSet.files.delete(location);
|
|
266
|
+
writeSet.files.set(location, null);
|
|
267
|
+
return true;
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* Note a folder to create in the running statement's write set. False when no statement is running.
|
|
271
|
+
* @param location
|
|
272
|
+
*/
|
|
273
|
+
exports.stageRemove = stageRemove;
|
|
274
|
+
const stageMakeDirectory = location => {
|
|
275
|
+
const writeSet = currentWriteSet();
|
|
276
|
+
if (!writeSet) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
writeSet.madeFolders.add(location);
|
|
280
|
+
return true;
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Mark a folder and everything in it removed in the running statement's write set: what the statement wrote or
|
|
284
|
+
* created inside it so far is dropped with it. False when no statement is running.
|
|
285
|
+
* @param location
|
|
286
|
+
*/
|
|
287
|
+
exports.stageMakeDirectory = stageMakeDirectory;
|
|
288
|
+
const stageRemoveDirectory = location => {
|
|
289
|
+
const writeSet = currentWriteSet();
|
|
290
|
+
if (!writeSet) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
for (const file of [...writeSet.files.keys()]) {
|
|
294
|
+
if (insideAny(file, new Set([location]))) {
|
|
295
|
+
writeSet.files.delete(file);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
for (const folder of [...writeSet.madeFolders]) {
|
|
299
|
+
if (insideAny(folder, new Set([location]))) {
|
|
300
|
+
writeSet.madeFolders.delete(folder);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
writeSet.removedFolders.add(location);
|
|
304
|
+
return true;
|
|
305
|
+
};
|
|
306
|
+
exports.stageRemoveDirectory = stageRemoveDirectory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.writeAtomically=exports.withWriteSet=exports.stageWrite=exports.stageRemoveDirectory=exports.stageRemove=exports.stageMakeDirectory=exports.pendingListing=exports.pendingFile=exports.pendingExists=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.map.delete-all.js"),require("core-js/modules/esnext.map.every.js"),require("core-js/modules/esnext.map.filter.js"),require("core-js/modules/esnext.map.find.js"),require("core-js/modules/esnext.map.find-key.js"),require("core-js/modules/esnext.map.includes.js"),require("core-js/modules/esnext.map.key-of.js"),require("core-js/modules/esnext.map.map-keys.js"),require("core-js/modules/esnext.map.map-values.js"),require("core-js/modules/esnext.map.merge.js"),require("core-js/modules/esnext.map.reduce.js"),require("core-js/modules/esnext.map.some.js"),require("core-js/modules/esnext.map.update.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache");function _interopRequireWildcard(r,s){if(!s&&r&&r.__esModule)return r;var t,o,i=Object.defineProperty,n={__proto__:null,default:r};if(Object(r)!==r)return n;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(r))return e.get(r);e.set(r,n)}for(o in r)"default"!==o&&{}.hasOwnProperty.call(r,o)&&((t=i&&Object.getOwnPropertyDescriptor(r,o))&&(t.get||t.set)?i(n,o,t):n[o]=r[o]);return n}const writeSets=new Map,currentWriteSet=()=>writeSets.get((0,_storagePath.storagePath)()),folderPrefix=e=>e.endsWith("/")?e:`${e}/`,insideAny=(e,r)=>{for(const s of r)if(e===s||e.startsWith(folderPrefix(s)))return!0;return!1},writeAtomically=async(e,r)=>{const s=`${e}.${crypto.randomUUID()}.tmp`,t=(0,_nodeFiles.nodeFiles)();try{await t.writeFile(s,r),await t.rename(s,e)}catch(e){throw await t.rm(s,{force:!0}).catch((()=>{})),e}};exports.writeAtomically=writeAtomically;const removeFolder=async e=>{(0,_readCache.cacheRemove)(e,!0),await(0,_nodeFiles.nodeFiles)().rm(e,{recursive:!0,force:!0}),(0,_readCache.cacheRemove)(e,!0)},commit=async e=>{const r=(0,_nodeFiles.nodeFiles)(),s=r=>{const s=folderPrefix(r);return[...e.madeFolders].some((e=>e===r||e.startsWith(s)))||[...e.files].some((([e,r])=>null!==r&&e.startsWith(s)))},t=[...e.removedFolders];for(const e of t.filter(s))await removeFolder(e);for(const s of e.madeFolders)await r.mkdir(s,{recursive:!0});for(const[r,s]of e.files)null!==s&&(await writeAtomically(r,s),(0,_readCache.cacheWrite)(r,s));for(const[s,t]of e.files)null===t&&((0,_readCache.cacheRemove)(s),await r.rm(s,{force:!0}),(0,_readCache.cacheRemove)(s));for(const e of t.filter((e=>!s(e))))await removeFolder(e)},withWriteSet=async e=>{const r=(0,_storagePath.storagePath)();if(!jsEnv.isNode||writeSets.has(r))return e();const s={files:new Map,madeFolders:new Set,removedFolders:new Set};let t;writeSets.set(r,s);try{t=await e()}finally{writeSets.delete(r)}return await commit(s),t};exports.withWriteSet=withWriteSet;const pendingFile=e=>{const r=currentWriteSet();if(r)return r.files.has(e)?r.files.get(e):insideAny(e,r.removedFolders)?null:void 0};exports.pendingFile=pendingFile;const pendingExists=e=>{const r=currentWriteSet();if(!r)return;if(r.files.has(e))return null!==r.files.get(e);const s=folderPrefix(e);return!(![...r.madeFolders].some((r=>r===e||r.startsWith(s)))&&![...r.files].some((([e,r])=>null!==r&&e.startsWith(s))))||!insideAny(e,r.removedFolders)&&void 0};exports.pendingExists=pendingExists;const pendingListing=(e,r)=>{const s=currentWriteSet();if(!s)return r;const t=folderPrefix(e),o=new Set(r.filter((e=>!insideAny(e,s.removedFolders))));for(const[e,r]of s.files)e.startsWith(t)&&(null===r?o.delete(e):o.add(e));return[...o]};exports.pendingListing=pendingListing;const stageWrite=(e,r)=>{const s=currentWriteSet();return!!s&&(s.files.delete(e),s.files.set(e,r),!0)};exports.stageWrite=stageWrite;const stageRemove=e=>{const r=currentWriteSet();return!!r&&(r.files.delete(e),r.files.set(e,null),!0)};exports.stageRemove=stageRemove;const stageMakeDirectory=e=>{const r=currentWriteSet();return!!r&&(r.madeFolders.add(e),!0)};exports.stageMakeDirectory=stageMakeDirectory;const stageRemoveDirectory=e=>{const r=currentWriteSet();if(!r)return!1;for(const s of[...r.files.keys()])insideAny(s,new Set([e]))&&r.files.delete(s);for(const s of[...r.madeFolders])insideAny(s,new Set([e]))&&r.madeFolders.delete(s);return r.removedFolders.add(e),!0};exports.stageRemoveDirectory=stageRemoveDirectory;
|
|
@@ -2,7 +2,33 @@ export type RuntimeSettings = {
|
|
|
2
2
|
databasePath: string;
|
|
3
3
|
relativePath: string;
|
|
4
4
|
enforceForeignKeys: boolean;
|
|
5
|
+
readConcurrency: number;
|
|
6
|
+
format: 'compact' | 'pretty';
|
|
7
|
+
packedReads?: boolean;
|
|
8
|
+
databasesPath?: string;
|
|
9
|
+
database?: string;
|
|
5
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* The folder of the database in use: `<databasesPath>/<database>/` once both are configured (see configure and the
|
|
13
|
+
* `use` statement), otherwise databasePath, as before there could be several.
|
|
14
|
+
*/
|
|
15
|
+
export declare const activeDatabasePath: () => string;
|
|
16
|
+
/**
|
|
17
|
+
* The folder whose calls are queued together (see withDatabaseLock): with several databases, all of them, since a
|
|
18
|
+
* call can switch between them (`use`) part way; otherwise the one database.
|
|
19
|
+
*/
|
|
20
|
+
export declare const lockPath: () => string;
|
|
21
|
+
/**
|
|
22
|
+
* The folder holding the databases, for create database, drop database, use and show databases.
|
|
23
|
+
* @throws {Error} When databasesPath isn't configured.
|
|
24
|
+
*/
|
|
25
|
+
export declare const databasesFolder: () => string;
|
|
26
|
+
/**
|
|
27
|
+
* Switch the database in use, from inside a call (the `use` statement, which holds the lock for every database in
|
|
28
|
+
* databasesPath, so no other call is running): configure() refuses to while calls run.
|
|
29
|
+
* @param name
|
|
30
|
+
*/
|
|
31
|
+
export declare const switchDatabase: (name: string) => void;
|
|
6
32
|
/**
|
|
7
33
|
* The folder a databasePath points to, so that `database/`, `./database` and its absolute path count as one database.
|
|
8
34
|
* Node only (only Node calls are counted, see trackDatabaseCall).
|
|
@@ -26,9 +52,20 @@ export declare const trackDatabaseCall: () => (() => void);
|
|
|
26
52
|
* mirroring MySQL's own foreign_key_checks setting, which is also toggleable rather than always
|
|
27
53
|
* on, since strict enforcement isn't always what every consumer wants.
|
|
28
54
|
*
|
|
55
|
+
* readConcurrency (default 16) is how many entry files a read has in flight at once (see retrieveFiles): in a browser,
|
|
56
|
+
* how many requests run together.
|
|
57
|
+
*
|
|
58
|
+
* format (default 'compact') is how files are written: 'compact' (no whitespace: smaller files that parse faster) or
|
|
59
|
+
* 'pretty' (indented by 2 spaces, for reading data in diffs). Either is read; formatDatabase rewrites a whole database
|
|
60
|
+
* in one.
|
|
61
|
+
*
|
|
62
|
+
* packedReads (default: true in a browser, false in Node) is whether reads use a record's packed file (see
|
|
63
|
+
* packDatabase) when it has one that matches the record, instead of reading each entry file.
|
|
64
|
+
*
|
|
29
65
|
* Changing databasePath while calls are still running or queued throws (see trackDatabaseCall): await them first.
|
|
30
66
|
* @param newSettings
|
|
31
67
|
* @throws {Error} When databasePath would point to another folder while database calls are in progress.
|
|
68
|
+
* @throws {Error} When format is neither 'compact' nor 'pretty'.
|
|
32
69
|
*/
|
|
33
70
|
export declare const configure: (newSettings: Partial<RuntimeSettings>) => void;
|
|
34
71
|
/**
|