json-fs-query 3.2.0 → 3.3.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 +257 -15
- package/browser/jsonFsQuery.js +2253 -293
- 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 +2 -1
- 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 +338 -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/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 +7 -3
|
@@ -23,6 +23,8 @@ var _splitEntityProperty = require("../utilities/parsers/splitEntityProperty");
|
|
|
23
23
|
var _config = require("../utilities/config");
|
|
24
24
|
var _keyIndexFiles = require("../utilities/keyIndexFiles");
|
|
25
25
|
var _storage = require("../storage");
|
|
26
|
+
var _packedTable = require("../utilities/packedTable");
|
|
27
|
+
var _knownFields = require("../utilities/knownFields");
|
|
26
28
|
/**
|
|
27
29
|
* Same reasoning as deleteEntity: a record object carries no memory of which entry file it came
|
|
28
30
|
* from, so find the file whose primary key value(s) match - a single field, or a composite of
|
|
@@ -74,7 +76,8 @@ const assertUniqueForUpdate = async (entity, record, oldData, newData, newValues
|
|
|
74
76
|
continue;
|
|
75
77
|
}
|
|
76
78
|
const checkKeys = key.fields.map(field => newData[field]);
|
|
77
|
-
|
|
79
|
+
// A null, or a field the row doesn't have (left out, or removed by this update), is never a duplicate
|
|
80
|
+
if (checkKeys.some(value => value === null || typeof value === 'undefined')) {
|
|
78
81
|
continue;
|
|
79
82
|
}
|
|
80
83
|
const isUnique = await (0, _keyUnique.keyUnique)(entity, key.fields, checkKeys);
|
|
@@ -99,7 +102,8 @@ const assertForeignKeysForUpdate = async (entity, record, oldData, newValues) =>
|
|
|
99
102
|
continue;
|
|
100
103
|
}
|
|
101
104
|
const field = key.fields[0];
|
|
102
|
-
|
|
105
|
+
// A null, or a field the update removes (undefined), references nothing
|
|
106
|
+
if (!Object.prototype.hasOwnProperty.call(newValues, field) || newValues[field] === null || typeof newValues[field] === 'undefined' || (0, _compareAs.sameValue)((0, _fieldType.fieldType)(record, field), newValues[field], oldData[field])) {
|
|
103
107
|
continue;
|
|
104
108
|
}
|
|
105
109
|
const {
|
|
@@ -169,7 +173,7 @@ const assertUniqueWithinUpdate = (entity, record, planned, newValues) => {
|
|
|
169
173
|
oldData,
|
|
170
174
|
newData
|
|
171
175
|
} of planned) {
|
|
172
|
-
if (!keyFieldsChanged(record, key, oldData, newValues) || key.fields.some(field => newData[field] === null)) {
|
|
176
|
+
if (!keyFieldsChanged(record, key, oldData, newValues) || key.fields.some(field => newData[field] === null || typeof newData[field] === 'undefined')) {
|
|
173
177
|
continue;
|
|
174
178
|
}
|
|
175
179
|
const value = (0, _computeKeyValue.computeKeyValue)(key.fields, newData);
|
|
@@ -192,6 +196,11 @@ const assertRequiredFields = (entity, record, newData) => {
|
|
|
192
196
|
* of the merged record - a field whose already-stored value doesn't match its declared type
|
|
193
197
|
* (nothing enforced this before typeCheck() existed) must not block an update that never touches
|
|
194
198
|
* that field.
|
|
199
|
+
*
|
|
200
|
+
* A null for an optional field that isn't nullable means the field is removed from the row (the
|
|
201
|
+
* field can't hold null, so this is the only thing it can mean, and the only way to clear one):
|
|
202
|
+
* it's kept as undefined here, so the key checks and indexes see the field change, and removed from
|
|
203
|
+
* the row that's written (see withoutRemoved).
|
|
195
204
|
* @param record
|
|
196
205
|
* @param values
|
|
197
206
|
*/
|
|
@@ -199,18 +208,40 @@ const applyFieldTypes = (record, values) => {
|
|
|
199
208
|
const typedValues = Object.assign({}, values);
|
|
200
209
|
for (const field of record.definition) {
|
|
201
210
|
if (Object.prototype.hasOwnProperty.call(typedValues, field.name)) {
|
|
202
|
-
typedValues[field.name] = (0, _typeCheck.typeCheck)(field.type, typedValues[field.name], field.nullable);
|
|
211
|
+
typedValues[field.name] = typedValues[field.name] === null && field.optional && !field.nullable ? undefined : (0, _typeCheck.typeCheck)(field.type, typedValues[field.name], field.nullable);
|
|
203
212
|
}
|
|
204
213
|
}
|
|
205
214
|
return typedValues;
|
|
206
215
|
};
|
|
216
|
+
/**
|
|
217
|
+
* A row without the fields an update removes (those it set to undefined, see applyFieldTypes).
|
|
218
|
+
* @param row
|
|
219
|
+
* @param typedValues
|
|
220
|
+
*/
|
|
221
|
+
const withoutRemoved = (row, typedValues) => {
|
|
222
|
+
const kept = Object.assign({}, row);
|
|
223
|
+
for (const field of Object.keys(typedValues)) {
|
|
224
|
+
if (typeof typedValues[field] === 'undefined') {
|
|
225
|
+
delete kept[field];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return kept;
|
|
229
|
+
};
|
|
207
230
|
const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
208
231
|
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
209
232
|
const primaryKey = record.keys.find(key => key.type === 'primary');
|
|
210
233
|
if (!primaryKey) {
|
|
211
234
|
throw new Error(`Cannot update "${entity}" without a primary key`);
|
|
212
235
|
}
|
|
236
|
+
// A field the record doesn't define would otherwise be stored outside its definition
|
|
237
|
+
(0, _knownFields.assertFieldsDefined)(entity, record, Object.keys(values || {}), 'set');
|
|
213
238
|
const typedValues = applyFieldTypes(record, values);
|
|
239
|
+
// A row is found by its primary key, so none of its fields can be cleared (an optional one could be, by null)
|
|
240
|
+
for (const field of primaryKey.fields) {
|
|
241
|
+
if (Object.prototype.hasOwnProperty.call(typedValues, field) && typeof typedValues[field] === 'undefined') {
|
|
242
|
+
throw new Error(`Cannot clear "${field}" on ${entity}: it's part of the primary key`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
214
245
|
// Check every row first and write only once all of them pass, so a row that fails leaves the others unchanged too
|
|
215
246
|
const planned = [];
|
|
216
247
|
for (const row of dataSet[entity] || []) {
|
|
@@ -223,7 +254,7 @@ const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
|
223
254
|
continue;
|
|
224
255
|
}
|
|
225
256
|
const oldData = await (0, _retrieveFile.retrieveFile)(`${record.path}/${fileName}`);
|
|
226
|
-
const newData = Object.assign({}, oldData, typedValues);
|
|
257
|
+
const newData = withoutRemoved(Object.assign({}, oldData, typedValues), typedValues);
|
|
227
258
|
await assertUniqueForUpdate(entity, record, oldData, newData, typedValues);
|
|
228
259
|
await assertForeignKeysForUpdate(entity, record, oldData, typedValues);
|
|
229
260
|
await assertNoDependentsForUpdate(entity, record, primaryKey, oldData, typedValues);
|
|
@@ -235,6 +266,9 @@ const updateEntity = async (entity = '', values = {}, dataSet = {}) => {
|
|
|
235
266
|
});
|
|
236
267
|
}
|
|
237
268
|
assertUniqueWithinUpdate(entity, record, planned, typedValues);
|
|
269
|
+
if (planned.length) {
|
|
270
|
+
await (0, _packedTable.discardPacked)(record.path);
|
|
271
|
+
}
|
|
238
272
|
for (const {
|
|
239
273
|
fileName,
|
|
240
274
|
oldData,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_compareAs=require("../utilities/compareAs"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_hasDependents=require("../introspect/policies/hasDependents"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_config=require("../utilities/config"),_keyIndexFiles=require("../utilities/keyIndexFiles"),_storage=require("../storage");const findEntryFile=async(e,t,i)=>{const r=(0,_fieldType.keyValueType)(e,t),o=async o=>(0,_compareAs.sameValue)(r,(0,_computeKeyValue.computeKeyValue)(t.fields,await(0,_retrieveFile.retrieveFile)(`${e.path}/${o}`)),i);for(const s of await(0,_keyIndexFiles.keyIndexFiles)(e,t,(e=>(0,_compareAs.sameValue)(r,e,i)))??[])if(await o(s))return s;for(const t of e.entries)if(await o(t))return t;return null},keyFieldsChanged=(e,t,i,r)=>t.fields.some((t=>Object.prototype.hasOwnProperty.call(r,t)&&!(0,_compareAs.sameValue)((0,_fieldType.fieldType)(e,t),r[t],i[t]))),assertUniqueForUpdate=async(e,t,i,r,o)=>{for(const s of t.keys){if("primary"!==s.type&&"unique"!==s.type||!keyFieldsChanged(t,s,i,o))continue;const n=s.fields.map((e=>r[e]));if(n.some((e=>null
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.updateEntity=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_updateIndex=require("../utilities/updateIndex"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_compareAs=require("../utilities/compareAs"),_keyUnique=require("../introspect/policies/keyUnique"),_typeCheck=require("../introspect/policies/typeCheck"),_foreignKeyExists=require("../introspect/policies/foreignKeyExists"),_hasDependents=require("../introspect/policies/hasDependents"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_config=require("../utilities/config"),_keyIndexFiles=require("../utilities/keyIndexFiles"),_storage=require("../storage"),_packedTable=require("../utilities/packedTable"),_knownFields=require("../utilities/knownFields");const findEntryFile=async(e,t,i)=>{const r=(0,_fieldType.keyValueType)(e,t),o=async o=>(0,_compareAs.sameValue)(r,(0,_computeKeyValue.computeKeyValue)(t.fields,await(0,_retrieveFile.retrieveFile)(`${e.path}/${o}`)),i);for(const s of await(0,_keyIndexFiles.keyIndexFiles)(e,t,(e=>(0,_compareAs.sameValue)(r,e,i)))??[])if(await o(s))return s;for(const t of e.entries)if(await o(t))return t;return null},keyFieldsChanged=(e,t,i,r)=>t.fields.some((t=>Object.prototype.hasOwnProperty.call(r,t)&&!(0,_compareAs.sameValue)((0,_fieldType.fieldType)(e,t),r[t],i[t]))),assertUniqueForUpdate=async(e,t,i,r,o)=>{for(const s of t.keys){if("primary"!==s.type&&"unique"!==s.type||!keyFieldsChanged(t,s,i,o))continue;const n=s.fields.map((e=>r[e]));if(n.some((e=>null==e)))continue;if(!await(0,_keyUnique.keyUnique)(e,s.fields,n))throw new Error(`Duplicate value for ${s.type} key "${s.fields.join(", ")}" on ${e}`)}},assertForeignKeysForUpdate=async(e,t,i,r)=>{for(const o of t.keys){if("foreign"!==o.type||1!==o.fields.length||!o.references||1!==o.references.length)continue;const s=o.fields[0];if(!Object.prototype.hasOwnProperty.call(r,s)||null===r[s]||void 0===r[s]||(0,_compareAs.sameValue)((0,_fieldType.fieldType)(t,s),r[s],i[s]))continue;const{entity:n,property:a}=(0,_splitEntityProperty.splitEntityProperty)(o.references[0].fields[0]);if(!await(0,_foreignKeyExists.foreignKeyExists)(n,a,r[s]))throw new Error(`Foreign key "${s}" on ${e} references a nonexistent ${n}.${a} = ${r[s]}`)}},assertNoDependentsForUpdate=async(e,t,i,r,o)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==i.fields.length||!keyFieldsChanged(t,i,r,o))return;const s=i.fields[0];if(await(0,_hasDependents.hasDependents)(e,s,r[s]))throw new Error(`Cannot update "${e}" where "${s}" = ${r[s]} - other records still reference it`)},reconcileIndexes=async(e,t,i,r,o)=>{for(const s of e.keys)keyFieldsChanged(e,s,t,r)&&(await(0,_removeFromIndex.removeFromIndex)(e.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,t),o,(0,_fieldType.keyValueType)(e,s)),await(0,_updateIndex.updateIndex)(e.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,i),o,(0,_fieldType.keyValueType)(e,s)))},assertUniqueWithinUpdate=(e,t,i,r)=>{for(const o of t.keys){if("primary"!==o.type&&"unique"!==o.type)continue;const s=[];for(const{oldData:n,newData:a}of i){if(!keyFieldsChanged(t,o,n,r)||o.fields.some((e=>null===a[e]||void 0===a[e])))continue;const i=(0,_computeKeyValue.computeKeyValue)(o.fields,a);if(s.some((e=>(0,_compareAs.sameValue)((0,_fieldType.keyValueType)(t,o),e,i))))throw new Error(`Duplicate value for ${o.type} key "${o.fields.join(", ")}" on ${e}`);s.push(i)}}},assertRequiredFields=(e,t,i)=>{for(const r of t.definition)if(!r.optional&&void 0===i[r.name])throw new Error(`Missing required field "${r.name}" for ${e}`)},applyFieldTypes=(e,t)=>{const i=Object.assign({},t);for(const t of e.definition)Object.prototype.hasOwnProperty.call(i,t.name)&&(i[t.name]=null===i[t.name]&&t.optional&&!t.nullable?void 0:(0,_typeCheck.typeCheck)(t.type,i[t.name],t.nullable));return i},withoutRemoved=(e,t)=>{const i=Object.assign({},e);for(const e of Object.keys(t))void 0===t[e]&&delete i[e];return i},updateEntity=async(e="",t={},i={})=>{const r=await(0,_retrieveRecord.retrieveRecord)(e),o=r.keys.find((e=>"primary"===e.type));if(!o)throw new Error(`Cannot update "${e}" without a primary key`);(0,_knownFields.assertFieldsDefined)(e,r,Object.keys(t||{}),"set");const s=applyFieldTypes(r,t);for(const t of o.fields)if(Object.prototype.hasOwnProperty.call(s,t)&&void 0===s[t])throw new Error(`Cannot clear "${t}" on ${e}: it's part of the primary key`);const n=[];for(const t of i[e]||[]){const i=await findEntryFile(r,o,(0,_computeKeyValue.computeKeyValue)(o.fields,t));if(!i)throw new Error(`Could not find entry for ${e} where "${o.fields.join(", ")}" = ${(0,_computeKeyValue.computeKeyValue)(o.fields,t)}`);if(n.some((e=>e.fileName===i)))continue;const a=await(0,_retrieveFile.retrieveFile)(`${r.path}/${i}`),l=withoutRemoved(Object.assign({},a,s),s);await assertUniqueForUpdate(e,r,a,l,s),await assertForeignKeysForUpdate(e,r,a,s),await assertNoDependentsForUpdate(e,r,o,a,s),assertRequiredFields(e,r,l),n.push({fileName:i,oldData:a,newData:l})}assertUniqueWithinUpdate(e,r,n,s),n.length&&await(0,_packedTable.discardPacked)(r.path);for(const{fileName:e,oldData:t,newData:i}of n)await reconcileIndexes(r,t,i,s,e),await(0,_storage.writeJson)(`${r.path}/${e}`,i);return i[e]=n.map((({newData:e})=>e)),i};exports.updateEntity=updateEntity;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where something in the folder holding the databases is (see databasesFolder), as storagePath gives it for a database:
|
|
3
|
+
* on disk in Node, behind relativePath over fetch() in a browser.
|
|
4
|
+
* @param path - A path inside that folder, such as `__DATABASES.json` or a database's name.
|
|
5
|
+
*/
|
|
6
|
+
export declare const databasesLocation: (path?: string) => string;
|
|
7
|
+
/**
|
|
8
|
+
* The databases' names, in the order they were created, from `__DATABASES.json` in the folder holding them (a list, so
|
|
9
|
+
* a browser can read it too: it can't list a folder). No list yet means no databases.
|
|
10
|
+
*/
|
|
11
|
+
export declare const readDatabaseList: () => Promise<string[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Replace the list of databases. Node only.
|
|
14
|
+
* @param names
|
|
15
|
+
*/
|
|
16
|
+
export declare const writeDatabaseList: (names: string[]) => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a database's folder exists. Node only.
|
|
19
|
+
* @param name
|
|
20
|
+
*/
|
|
21
|
+
export declare const databaseFolderExists: (name: string) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Create a database's (empty) folder. Node only.
|
|
24
|
+
* @param name
|
|
25
|
+
*/
|
|
26
|
+
export declare const makeDatabaseFolder: (name: string) => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Delete a database's folder and everything in it, and forget anything read from it. Node only.
|
|
29
|
+
* @param name
|
|
30
|
+
*/
|
|
31
|
+
export declare const removeDatabaseFolder: (name: string) => Promise<void>;
|
|
32
|
+
//# sourceMappingURL=databases.d.ts.map
|
|
@@ -0,0 +1,93 @@
|
|
|
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.writeDatabaseList = exports.removeDatabaseFolder = exports.readDatabaseList = exports.makeDatabaseFolder = exports.databasesLocation = exports.databaseFolderExists = void 0;
|
|
8
|
+
require("core-js/modules/es.json.stringify.js");
|
|
9
|
+
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
10
|
+
var _config = require("../utilities/config");
|
|
11
|
+
var _nodeFiles = require("./nodeFiles");
|
|
12
|
+
var _readCache = require("./readCache");
|
|
13
|
+
var _writeSet = require("./writeSet");
|
|
14
|
+
var e;
|
|
15
|
+
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; }
|
|
16
|
+
/**
|
|
17
|
+
* Where something in the folder holding the databases is (see databasesFolder), as storagePath gives it for a database:
|
|
18
|
+
* on disk in Node, behind relativePath over fetch() in a browser.
|
|
19
|
+
* @param path - A path inside that folder, such as `__DATABASES.json` or a database's name.
|
|
20
|
+
*/
|
|
21
|
+
const databasesLocation = (path = '') => {
|
|
22
|
+
const relativePath = jsEnv.isBrowser ? (0, _config.getSetting)('relativePath', '') : '';
|
|
23
|
+
return `${relativePath}${(0, _config.databasesFolder)()}${path}`;
|
|
24
|
+
};
|
|
25
|
+
exports.databasesLocation = databasesLocation;
|
|
26
|
+
const listLocation = () => databasesLocation('__DATABASES.json');
|
|
27
|
+
/**
|
|
28
|
+
* The databases' names, in the order they were created, from `__DATABASES.json` in the folder holding them (a list, so
|
|
29
|
+
* a browser can read it too: it can't list a folder). No list yet means no databases.
|
|
30
|
+
*/
|
|
31
|
+
const readDatabaseList = async () => {
|
|
32
|
+
let text;
|
|
33
|
+
try {
|
|
34
|
+
text = jsEnv.isNode ? await (0, _nodeFiles.nodeFiles)().readFile(listLocation(), 'utf8') : await fetch(listLocation()).then(response => response.ok === false ? '[]' : response.text());
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if (jsEnv.isNode && error?.code !== 'ENOENT') {
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const names = JSON.parse(text);
|
|
43
|
+
return Array.isArray(names) ? names : [];
|
|
44
|
+
} catch (error) {
|
|
45
|
+
// A static host answers a missing file with a page that isn't JSON
|
|
46
|
+
if (!jsEnv.isNode) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Could not read ${listLocation()}: ${error.message}`);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Replace the list of databases. Node only.
|
|
54
|
+
* @param names
|
|
55
|
+
*/
|
|
56
|
+
exports.readDatabaseList = readDatabaseList;
|
|
57
|
+
const writeDatabaseList = async names => {
|
|
58
|
+
await (0, _nodeFiles.nodeFiles)().mkdir(databasesLocation(), {
|
|
59
|
+
recursive: true
|
|
60
|
+
});
|
|
61
|
+
await (0, _writeSet.writeAtomically)(listLocation(), JSON.stringify(names));
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Whether a database's folder exists. Node only.
|
|
65
|
+
* @param name
|
|
66
|
+
*/
|
|
67
|
+
exports.writeDatabaseList = writeDatabaseList;
|
|
68
|
+
const databaseFolderExists = name => require('fs').existsSync(databasesLocation(name));
|
|
69
|
+
/**
|
|
70
|
+
* Create a database's (empty) folder. Node only.
|
|
71
|
+
* @param name
|
|
72
|
+
*/
|
|
73
|
+
exports.databaseFolderExists = databaseFolderExists;
|
|
74
|
+
const makeDatabaseFolder = async name => {
|
|
75
|
+
await (0, _nodeFiles.nodeFiles)().mkdir(databasesLocation(name), {
|
|
76
|
+
recursive: true
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Delete a database's folder and everything in it, and forget anything read from it. Node only.
|
|
81
|
+
* @param name
|
|
82
|
+
*/
|
|
83
|
+
exports.makeDatabaseFolder = makeDatabaseFolder;
|
|
84
|
+
const removeDatabaseFolder = async name => {
|
|
85
|
+
const location = databasesLocation(name);
|
|
86
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
87
|
+
await (0, _nodeFiles.nodeFiles)().rm(location, {
|
|
88
|
+
recursive: true,
|
|
89
|
+
force: true
|
|
90
|
+
});
|
|
91
|
+
(0, _readCache.cacheRemove)(location, true);
|
|
92
|
+
};
|
|
93
|
+
exports.removeDatabaseFolder = removeDatabaseFolder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.writeDatabaseList=exports.removeDatabaseFolder=exports.readDatabaseList=exports.makeDatabaseFolder=exports.databasesLocation=exports.databaseFolderExists=void 0,require("core-js/modules/es.json.stringify.js");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("../utilities/config"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache"),_writeSet=require("./writeSet");function _interopRequireWildcard(a,t){if(!t&&a&&a.__esModule)return a;var s,r,o=Object.defineProperty,i={__proto__:null,default:a};if(Object(a)!==a)return i;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(a))return e.get(a);e.set(a,i)}for(r in a)"default"!==r&&{}.hasOwnProperty.call(a,r)&&((s=o&&Object.getOwnPropertyDescriptor(a,r))&&(s.get||s.set)?o(i,r,s):i[r]=a[r]);return i}const databasesLocation=(e="")=>`${jsEnv.isBrowser?(0,_config.getSetting)("relativePath",""):""}${(0,_config.databasesFolder)()}${e}`;exports.databasesLocation=databasesLocation;const listLocation=()=>databasesLocation("__DATABASES.json"),readDatabaseList=async()=>{let e;try{e=jsEnv.isNode?await(0,_nodeFiles.nodeFiles)().readFile(listLocation(),"utf8"):await fetch(listLocation()).then((e=>!1===e.ok?"[]":e.text()))}catch(e){if(jsEnv.isNode&&"ENOENT"!==e?.code)throw e;return[]}try{const a=JSON.parse(e);return Array.isArray(a)?a:[]}catch(e){if(!jsEnv.isNode)return[];throw new Error(`Could not read ${listLocation()}: ${e.message}`)}};exports.readDatabaseList=readDatabaseList;const writeDatabaseList=async e=>{await(0,_nodeFiles.nodeFiles)().mkdir(databasesLocation(),{recursive:!0}),await(0,_writeSet.writeAtomically)(listLocation(),JSON.stringify(e))};exports.writeDatabaseList=writeDatabaseList;const databaseFolderExists=e=>require("fs").existsSync(databasesLocation(e));exports.databaseFolderExists=databaseFolderExists;const makeDatabaseFolder=async e=>{await(0,_nodeFiles.nodeFiles)().mkdir(databasesLocation(e),{recursive:!0})};exports.makeDatabaseFolder=makeDatabaseFolder;const removeDatabaseFolder=async e=>{const a=databasesLocation(e);(0,_readCache.cacheRemove)(a,!0),await(0,_nodeFiles.nodeFiles)().rm(a,{recursive:!0,force:!0}),(0,_readCache.cacheRemove)(a,!0)};exports.removeDatabaseFolder=removeDatabaseFolder;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Whether a file (or folder) of the database exists
|
|
2
|
+
* Whether a file (or folder) of the database exists, counting what the running statement has written or deleted so
|
|
3
|
+
* far (see withWriteSet). Node only, like the schema statements that use it.
|
|
3
4
|
* @param path - A path inside the database, such as `users.json`.
|
|
4
5
|
*/
|
|
5
6
|
export declare const fileExists: (path: string) => boolean;
|
|
@@ -5,14 +5,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.fileExists = void 0;
|
|
7
7
|
var _storagePath = require("./storagePath");
|
|
8
|
+
var _writeSet = require("./writeSet");
|
|
8
9
|
/**
|
|
9
|
-
* Whether a file (or folder) of the database exists
|
|
10
|
+
* Whether a file (or folder) of the database exists, counting what the running statement has written or deleted so
|
|
11
|
+
* far (see withWriteSet). Node only, like the schema statements that use it.
|
|
10
12
|
* @param path - A path inside the database, such as `users.json`.
|
|
11
13
|
*/
|
|
12
14
|
const fileExists = path => {
|
|
15
|
+
const location = (0, _storagePath.storagePath)(path);
|
|
16
|
+
const pending = (0, _writeSet.pendingExists)(location);
|
|
17
|
+
if (pending !== undefined) {
|
|
18
|
+
return pending;
|
|
19
|
+
}
|
|
13
20
|
const {
|
|
14
21
|
existsSync
|
|
15
22
|
} = require('fs');
|
|
16
|
-
return existsSync(
|
|
23
|
+
return existsSync(location);
|
|
17
24
|
};
|
|
18
25
|
exports.fileExists = fileExists;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.fileExists=void 0;var _storagePath=require("./storagePath");const fileExists=e=>{const{existsSync:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.fileExists=void 0;var _storagePath=require("./storagePath"),_writeSet=require("./writeSet");const fileExists=e=>{const t=(0,_storagePath.storagePath)(e),s=(0,_writeSet.pendingExists)(t);if(void 0!==s)return s;const{existsSync:r}=require("fs");return r(t)};exports.fileExists=fileExists;
|
|
@@ -6,11 +6,14 @@
|
|
|
6
6
|
* functions is what lets a read cache, batched writes and other storage backends come later without touching queries.
|
|
7
7
|
*/
|
|
8
8
|
export { storagePath } from './storagePath';
|
|
9
|
-
export { readJson } from './readJson';
|
|
10
|
-
export { writeJson } from './writeJson';
|
|
9
|
+
export { readJson, readText } from './readJson';
|
|
10
|
+
export { writeJson, jsonText } from './writeJson';
|
|
11
11
|
export { makeDirectory } from './makeDirectory';
|
|
12
12
|
export { removeFile } from './removeFile';
|
|
13
13
|
export { removeDirectory } from './removeDirectory';
|
|
14
14
|
export { fileExists } from './fileExists';
|
|
15
|
+
export { listFiles } from './listFiles';
|
|
16
|
+
export { databasesLocation, readDatabaseList, writeDatabaseList, databaseFolderExists, makeDatabaseFolder, removeDatabaseFolder } from './databases';
|
|
15
17
|
export { withReadCache } from './readCache';
|
|
18
|
+
export { withWriteSet } from './writeSet';
|
|
16
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -3,24 +3,72 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
Object.defineProperty(exports, "databaseFolderExists", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _databases.databaseFolderExists;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "databasesLocation", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _databases.databasesLocation;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
6
18
|
Object.defineProperty(exports, "fileExists", {
|
|
7
19
|
enumerable: true,
|
|
8
20
|
get: function () {
|
|
9
21
|
return _fileExists.fileExists;
|
|
10
22
|
}
|
|
11
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "jsonText", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _writeJson.jsonText;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "listFiles", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _listFiles.listFiles;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "makeDatabaseFolder", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _databases.makeDatabaseFolder;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
12
42
|
Object.defineProperty(exports, "makeDirectory", {
|
|
13
43
|
enumerable: true,
|
|
14
44
|
get: function () {
|
|
15
45
|
return _makeDirectory.makeDirectory;
|
|
16
46
|
}
|
|
17
47
|
});
|
|
48
|
+
Object.defineProperty(exports, "readDatabaseList", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _databases.readDatabaseList;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
18
54
|
Object.defineProperty(exports, "readJson", {
|
|
19
55
|
enumerable: true,
|
|
20
56
|
get: function () {
|
|
21
57
|
return _readJson.readJson;
|
|
22
58
|
}
|
|
23
59
|
});
|
|
60
|
+
Object.defineProperty(exports, "readText", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _readJson.readText;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "removeDatabaseFolder", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _databases.removeDatabaseFolder;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
24
72
|
Object.defineProperty(exports, "removeDirectory", {
|
|
25
73
|
enumerable: true,
|
|
26
74
|
get: function () {
|
|
@@ -45,6 +93,18 @@ Object.defineProperty(exports, "withReadCache", {
|
|
|
45
93
|
return _readCache.withReadCache;
|
|
46
94
|
}
|
|
47
95
|
});
|
|
96
|
+
Object.defineProperty(exports, "withWriteSet", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _writeSet.withWriteSet;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(exports, "writeDatabaseList", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
get: function () {
|
|
105
|
+
return _databases.writeDatabaseList;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
48
108
|
Object.defineProperty(exports, "writeJson", {
|
|
49
109
|
enumerable: true,
|
|
50
110
|
get: function () {
|
|
@@ -58,4 +118,7 @@ var _makeDirectory = require("./makeDirectory");
|
|
|
58
118
|
var _removeFile = require("./removeFile");
|
|
59
119
|
var _removeDirectory = require("./removeDirectory");
|
|
60
120
|
var _fileExists = require("./fileExists");
|
|
61
|
-
var
|
|
121
|
+
var _listFiles = require("./listFiles");
|
|
122
|
+
var _databases = require("./databases");
|
|
123
|
+
var _readCache = require("./readCache");
|
|
124
|
+
var _writeSet = require("./writeSet");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"fileExists",{enumerable:!0,get:function(){return _fileExists.fileExists}}),Object.defineProperty(exports,"makeDirectory",{enumerable:!0,get:function(){return _makeDirectory.makeDirectory}}),Object.defineProperty(exports,"readJson",{enumerable:!0,get:function(){return _readJson.readJson}}),Object.defineProperty(exports,"removeDirectory",{enumerable:!0,get:function(){return _removeDirectory.removeDirectory}}),Object.defineProperty(exports,"removeFile",{enumerable:!0,get:function(){return _removeFile.removeFile}}),Object.defineProperty(exports,"storagePath",{enumerable:!0,get:function(){return _storagePath.storagePath}}),Object.defineProperty(exports,"withReadCache",{enumerable:!0,get:function(){return _readCache.withReadCache}}),Object.defineProperty(exports,"writeJson",{enumerable:!0,get:function(){return _writeJson.writeJson}});var _storagePath=require("./storagePath"),_readJson=require("./readJson"),_writeJson=require("./writeJson"),_makeDirectory=require("./makeDirectory"),_removeFile=require("./removeFile"),_removeDirectory=require("./removeDirectory"),_fileExists=require("./fileExists"),_readCache=require("./readCache");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"databaseFolderExists",{enumerable:!0,get:function(){return _databases.databaseFolderExists}}),Object.defineProperty(exports,"databasesLocation",{enumerable:!0,get:function(){return _databases.databasesLocation}}),Object.defineProperty(exports,"fileExists",{enumerable:!0,get:function(){return _fileExists.fileExists}}),Object.defineProperty(exports,"jsonText",{enumerable:!0,get:function(){return _writeJson.jsonText}}),Object.defineProperty(exports,"listFiles",{enumerable:!0,get:function(){return _listFiles.listFiles}}),Object.defineProperty(exports,"makeDatabaseFolder",{enumerable:!0,get:function(){return _databases.makeDatabaseFolder}}),Object.defineProperty(exports,"makeDirectory",{enumerable:!0,get:function(){return _makeDirectory.makeDirectory}}),Object.defineProperty(exports,"readDatabaseList",{enumerable:!0,get:function(){return _databases.readDatabaseList}}),Object.defineProperty(exports,"readJson",{enumerable:!0,get:function(){return _readJson.readJson}}),Object.defineProperty(exports,"readText",{enumerable:!0,get:function(){return _readJson.readText}}),Object.defineProperty(exports,"removeDatabaseFolder",{enumerable:!0,get:function(){return _databases.removeDatabaseFolder}}),Object.defineProperty(exports,"removeDirectory",{enumerable:!0,get:function(){return _removeDirectory.removeDirectory}}),Object.defineProperty(exports,"removeFile",{enumerable:!0,get:function(){return _removeFile.removeFile}}),Object.defineProperty(exports,"storagePath",{enumerable:!0,get:function(){return _storagePath.storagePath}}),Object.defineProperty(exports,"withReadCache",{enumerable:!0,get:function(){return _readCache.withReadCache}}),Object.defineProperty(exports,"withWriteSet",{enumerable:!0,get:function(){return _writeSet.withWriteSet}}),Object.defineProperty(exports,"writeDatabaseList",{enumerable:!0,get:function(){return _databases.writeDatabaseList}}),Object.defineProperty(exports,"writeJson",{enumerable:!0,get:function(){return _writeJson.writeJson}});var _storagePath=require("./storagePath"),_readJson=require("./readJson"),_writeJson=require("./writeJson"),_makeDirectory=require("./makeDirectory"),_removeFile=require("./removeFile"),_removeDirectory=require("./removeDirectory"),_fileExists=require("./fileExists"),_listFiles=require("./listFiles"),_databases=require("./databases"),_readCache=require("./readCache"),_writeSet=require("./writeSet");
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every file in a folder of the database and the folders inside it, as paths inside the database (such as
|
|
3
|
+
* `users/1.json`), sorted. During a statement it counts what the statement has written or deleted (see withWriteSet).
|
|
4
|
+
* A folder that doesn't exist has no files. Node only.
|
|
5
|
+
* @param path - A path inside the database, such as `users`. Empty for the whole database.
|
|
6
|
+
*/
|
|
7
|
+
export declare const listFiles: (path?: string) => Promise<string[]>;
|
|
8
|
+
//# sourceMappingURL=listFiles.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.listFiles = void 0;
|
|
7
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
9
|
+
var _storagePath = require("./storagePath");
|
|
10
|
+
var _nodeFiles = require("./nodeFiles");
|
|
11
|
+
var _writeSet = require("./writeSet");
|
|
12
|
+
/**
|
|
13
|
+
* The files in `folder` and the folders inside it, as paths relative to the database (`base` is the folder's own).
|
|
14
|
+
* Walks one folder at a time with a plain readdir, so it needs no `recursive` option (which older Node versions
|
|
15
|
+
* ignore without an error, listing only the top folder) and no `Dirent.parentPath`.
|
|
16
|
+
* @param base - The folder's path inside the database, ending in `/` (empty for the database itself).
|
|
17
|
+
*/
|
|
18
|
+
const walk = async base => {
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = await (0, _nodeFiles.nodeFiles)().readdir((0, _storagePath.storagePath)(base), {
|
|
22
|
+
withFileTypes: true
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (error?.code === 'ENOENT') {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
const paths = [];
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.isDirectory()) {
|
|
33
|
+
paths.push(...(await walk(`${base}${entry.name}/`)));
|
|
34
|
+
} else if (entry.isFile()) {
|
|
35
|
+
paths.push(`${base}${entry.name}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return paths;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Every file in a folder of the database and the folders inside it, as paths inside the database (such as
|
|
42
|
+
* `users/1.json`), sorted. During a statement it counts what the statement has written or deleted (see withWriteSet).
|
|
43
|
+
* A folder that doesn't exist has no files. Node only.
|
|
44
|
+
* @param path - A path inside the database, such as `users`. Empty for the whole database.
|
|
45
|
+
*/
|
|
46
|
+
const listFiles = async (path = '') => {
|
|
47
|
+
const base = path ? `${path.replace(/\/+$/, '')}/` : '';
|
|
48
|
+
const onDisk = (await walk(base)).map(file => (0, _storagePath.storagePath)(file));
|
|
49
|
+
const root = (0, _storagePath.storagePath)();
|
|
50
|
+
return (0, _writeSet.pendingListing)((0, _storagePath.storagePath)(path), onDisk).map(location => location.slice(root.length)).sort();
|
|
51
|
+
};
|
|
52
|
+
exports.listFiles = listFiles;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.listFiles=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js");var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_writeSet=require("./writeSet");const walk=async e=>{let t;try{t=await(0,_nodeFiles.nodeFiles)().readdir((0,_storagePath.storagePath)(e),{withFileTypes:!0})}catch(e){if("ENOENT"===e?.code)return[];throw e}const r=[];for(const s of t)s.isDirectory()?r.push(...await walk(`${e}${s.name}/`)):s.isFile()&&r.push(`${e}${s.name}`);return r},listFiles=async(e="")=>{const t=e?`${e.replace(/\/+$/,"")}/`:"",r=(await walk(t)).map((e=>(0,_storagePath.storagePath)(e))),s=(0,_storagePath.storagePath)();return(0,_writeSet.pendingListing)((0,_storagePath.storagePath)(e),r).map((e=>e.slice(s.length))).sort()};exports.listFiles=listFiles;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Create a folder of the database, and any missing folders above it (doing nothing if it already exists).
|
|
2
|
+
* Create a folder of the database, and any missing folders above it (doing nothing if it already exists). During a
|
|
3
|
+
* statement it's created with the statement's other changes (see withWriteSet). Node only.
|
|
3
4
|
* @param path - A path inside the database, such as `users`. Empty for the database folder itself.
|
|
4
5
|
*/
|
|
5
6
|
export declare const makeDirectory: (path?: string) => Promise<void>;
|
|
@@ -6,12 +6,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.makeDirectory = void 0;
|
|
7
7
|
var _storagePath = require("./storagePath");
|
|
8
8
|
var _nodeFiles = require("./nodeFiles");
|
|
9
|
+
var _writeSet = require("./writeSet");
|
|
9
10
|
/**
|
|
10
|
-
* Create a folder of the database, and any missing folders above it (doing nothing if it already exists).
|
|
11
|
+
* Create a folder of the database, and any missing folders above it (doing nothing if it already exists). During a
|
|
12
|
+
* statement it's created with the statement's other changes (see withWriteSet). Node only.
|
|
11
13
|
* @param path - A path inside the database, such as `users`. Empty for the database folder itself.
|
|
12
14
|
*/
|
|
13
15
|
const makeDirectory = async (path = '') => {
|
|
14
|
-
|
|
16
|
+
const location = (0, _storagePath.storagePath)(path);
|
|
17
|
+
if ((0, _writeSet.stageMakeDirectory)(location)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await (0, _nodeFiles.nodeFiles)().mkdir(location, {
|
|
15
21
|
recursive: true
|
|
16
22
|
});
|
|
17
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.makeDirectory=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles");const makeDirectory=async(e="")=>{
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.makeDirectory=void 0;var _storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_writeSet=require("./writeSet");const makeDirectory=async(e="")=>{const r=(0,_storagePath.storagePath)(e);(0,_writeSet.stageMakeDirectory)(r)||await(0,_nodeFiles.nodeFiles)().mkdir(r,{recursive:!0})};exports.makeDirectory=makeDirectory;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read one file of the database as text, from wherever readJson would read it (the statement's write set, the read
|
|
3
|
+
* cache, then storage).
|
|
4
|
+
* @param path - A path inside the database, such as `users.json`.
|
|
5
|
+
* @throws {Error} When the file can't be read.
|
|
6
|
+
*/
|
|
7
|
+
export declare const readText: (path: string) => Promise<string>;
|
|
1
8
|
/**
|
|
2
9
|
* Read and parse one JSON file of the database: from disk in Node, over `fetch()` in a browser (see storagePath for
|
|
3
|
-
* where it's looked for). During a
|
|
10
|
+
* where it's looked for). During a statement, a file it has written or deleted is answered from its write set (see
|
|
11
|
+
* withWriteSet); otherwise, during a call, a file already read is answered from the read cache (see withReadCache).
|
|
4
12
|
* @param path - A path inside the database, such as `users.json`.
|
|
5
13
|
* @throws {Error} When the file can't be read or isn't valid JSON (the error from the file system, fetch or JSON.parse).
|
|
6
14
|
*/
|
|
@@ -4,22 +4,35 @@ require("core-js/modules/esnext.weak-map.delete-all.js");
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.readJson = void 0;
|
|
7
|
+
exports.readText = exports.readJson = void 0;
|
|
8
8
|
var jsEnv = _interopRequireWildcard(require("browser-or-node"));
|
|
9
9
|
var _storagePath = require("./storagePath");
|
|
10
10
|
var _nodeFiles = require("./nodeFiles");
|
|
11
11
|
var _readCache = require("./readCache");
|
|
12
|
+
var _writeSet = require("./writeSet");
|
|
12
13
|
var e;
|
|
13
14
|
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; }
|
|
14
15
|
/**
|
|
15
|
-
* Read
|
|
16
|
-
*
|
|
16
|
+
* Read one file of the database as text, from wherever readJson would read it (the statement's write set, the read
|
|
17
|
+
* cache, then storage).
|
|
17
18
|
* @param path - A path inside the database, such as `users.json`.
|
|
18
|
-
* @throws {Error} When the file can't be read
|
|
19
|
+
* @throws {Error} When the file can't be read.
|
|
19
20
|
*/
|
|
20
|
-
const
|
|
21
|
+
const readText = async path => {
|
|
21
22
|
const location = (0, _storagePath.storagePath)(path);
|
|
22
|
-
const
|
|
23
|
-
|
|
23
|
+
const pending = (0, _writeSet.pendingFile)(location);
|
|
24
|
+
if (pending === null) {
|
|
25
|
+
throw new Error(`ENOENT: no such file or directory, open '${location}' (deleted by this statement)`);
|
|
26
|
+
}
|
|
27
|
+
return typeof pending === 'string' ? pending : (0, _readCache.cachedRead)(location, () => jsEnv.isNode ? (0, _nodeFiles.nodeFiles)().readFile(location, 'utf8') : fetch(location).then(response => response.text()));
|
|
24
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Read and parse one JSON file of the database: from disk in Node, over `fetch()` in a browser (see storagePath for
|
|
31
|
+
* where it's looked for). During a statement, a file it has written or deleted is answered from its write set (see
|
|
32
|
+
* withWriteSet); otherwise, during a call, a file already read is answered from the read cache (see withReadCache).
|
|
33
|
+
* @param path - A path inside the database, such as `users.json`.
|
|
34
|
+
* @throws {Error} When the file can't be read or isn't valid JSON (the error from the file system, fetch or JSON.parse).
|
|
35
|
+
*/
|
|
36
|
+
exports.readText = readText;
|
|
37
|
+
const readJson = async path => JSON.parse(await readText(path));
|
|
25
38
|
exports.readJson = readJson;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.readJson=void 0;var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache");function _interopRequireWildcard(r,t){if(!t&&r&&r.__esModule)return r;var a,o,
|
|
1
|
+
"use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.readText=exports.readJson=void 0;var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_storagePath=require("./storagePath"),_nodeFiles=require("./nodeFiles"),_readCache=require("./readCache"),_writeSet=require("./writeSet");function _interopRequireWildcard(r,t){if(!t&&r&&r.__esModule)return r;var a,o,n=Object.defineProperty,s={__proto__:null,default:r};if(Object(r)!==r)return s;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(r))return e.get(r);e.set(r,s)}for(o in r)"default"!==o&&{}.hasOwnProperty.call(r,o)&&((a=n&&Object.getOwnPropertyDescriptor(r,o))&&(a.get||a.set)?n(s,o,a):s[o]=r[o]);return s}const readText=async e=>{const r=(0,_storagePath.storagePath)(e),t=(0,_writeSet.pendingFile)(r);if(null===t)throw new Error(`ENOENT: no such file or directory, open '${r}' (deleted by this statement)`);return"string"==typeof t?t:(0,_readCache.cachedRead)(r,(()=>jsEnv.isNode?(0,_nodeFiles.nodeFiles)().readFile(r,"utf8"):fetch(r).then((e=>e.text()))))};exports.readText=readText;const readJson=async e=>JSON.parse(await readText(e));exports.readJson=readJson;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Delete a folder of the database and everything in it; a folder that doesn't exist is left alone.
|
|
2
|
+
* Delete a folder of the database and everything in it; a folder that doesn't exist is left alone. During a statement
|
|
3
|
+
* it's removed with the statement's other changes (see withWriteSet), and reads in the statement already find
|
|
4
|
+
* everything in it gone. Node only.
|
|
3
5
|
* @param path - A path inside the database, such as `__indexes/users`.
|
|
4
6
|
*/
|
|
5
7
|
export declare const removeDirectory: (path: string) => Promise<void>;
|