json-fs-query 3.1.3 → 3.2.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.
Files changed (109) hide show
  1. package/browser/jsonFsQuery.js +2172 -5301
  2. package/browser/jsonFsQuery.min.js +1 -1
  3. package/dist/data/introspect/create.js +7 -22
  4. package/dist/data/introspect/create.min.js +1 -1
  5. package/dist/data/introspect/drop.js +5 -15
  6. package/dist/data/introspect/drop.min.js +1 -1
  7. package/dist/data/introspect/policies/foreignKeyExists.d.ts +2 -0
  8. package/dist/data/introspect/policies/foreignKeyExists.js +9 -3
  9. package/dist/data/introspect/policies/foreignKeyExists.min.js +1 -1
  10. package/dist/data/introspect/policies/hasDependents.d.ts +3 -3
  11. package/dist/data/introspect/policies/hasDependents.js +11 -3
  12. package/dist/data/introspect/policies/hasDependents.min.js +1 -1
  13. package/dist/data/introspect/policies/keyUnique.d.ts +3 -0
  14. package/dist/data/introspect/policies/keyUnique.js +10 -0
  15. package/dist/data/introspect/policies/keyUnique.min.js +1 -1
  16. package/dist/data/queries/deleteEntity.js +29 -18
  17. package/dist/data/queries/deleteEntity.min.js +1 -1
  18. package/dist/data/queries/insertEntity.js +6 -8
  19. package/dist/data/queries/insertEntity.min.js +1 -1
  20. package/dist/data/queries/joinEntity.d.ts +15 -0
  21. package/dist/data/queries/joinEntity.js +91 -15
  22. package/dist/data/queries/joinEntity.min.js +1 -1
  23. package/dist/data/queries/updateEntity.js +15 -10
  24. package/dist/data/queries/updateEntity.min.js +1 -1
  25. package/dist/data/storage/fileExists.d.ts +6 -0
  26. package/dist/data/storage/fileExists.js +18 -0
  27. package/dist/data/storage/fileExists.min.js +1 -0
  28. package/dist/data/storage/index.d.ts +16 -0
  29. package/dist/data/storage/index.js +61 -0
  30. package/dist/data/storage/index.min.js +1 -0
  31. package/dist/data/storage/makeDirectory.d.ts +6 -0
  32. package/dist/data/storage/makeDirectory.js +18 -0
  33. package/dist/data/storage/makeDirectory.min.js +1 -0
  34. package/dist/data/storage/nodeFiles.d.ts +6 -0
  35. package/dist/data/storage/nodeFiles.js +12 -0
  36. package/dist/data/storage/nodeFiles.min.js +1 -0
  37. package/dist/data/storage/readCache.d.ts +37 -0
  38. package/dist/data/storage/readCache.js +117 -0
  39. package/dist/data/storage/readCache.min.js +1 -0
  40. package/dist/data/storage/readJson.d.ts +8 -0
  41. package/dist/data/storage/readJson.js +25 -0
  42. package/dist/data/storage/readJson.min.js +1 -0
  43. package/dist/data/storage/removeDirectory.d.ts +6 -0
  44. package/dist/data/storage/removeDirectory.js +24 -0
  45. package/dist/data/storage/removeDirectory.min.js +1 -0
  46. package/dist/data/storage/removeFile.d.ts +7 -0
  47. package/dist/data/storage/removeFile.js +22 -0
  48. package/dist/data/storage/removeFile.min.js +1 -0
  49. package/dist/data/storage/storagePath.d.ts +11 -0
  50. package/dist/data/storage/storagePath.js +25 -0
  51. package/dist/data/storage/storagePath.min.js +1 -0
  52. package/dist/data/storage/writeJson.d.ts +8 -0
  53. package/dist/data/storage/writeJson.js +23 -0
  54. package/dist/data/storage/writeJson.min.js +1 -0
  55. package/dist/data/utilities/compareAs.d.ts +1 -0
  56. package/dist/data/utilities/compareAs.js +2 -2
  57. package/dist/data/utilities/compareAs.min.js +1 -1
  58. package/dist/data/utilities/databaseLock.d.ts +2 -0
  59. package/dist/data/utilities/databaseLock.js +5 -2
  60. package/dist/data/utilities/databaseLock.min.js +1 -1
  61. package/dist/data/utilities/deregisterRecord.js +4 -10
  62. package/dist/data/utilities/deregisterRecord.min.js +1 -1
  63. package/dist/data/utilities/indexHas.d.ts +13 -0
  64. package/dist/data/utilities/indexHas.js +48 -0
  65. package/dist/data/utilities/indexHas.min.js +1 -0
  66. package/dist/data/utilities/joinBases.d.ts +29 -0
  67. package/dist/data/utilities/joinBases.js +136 -0
  68. package/dist/data/utilities/joinBases.min.js +1 -0
  69. package/dist/data/utilities/joinKey.d.ts +17 -0
  70. package/dist/data/utilities/joinKey.js +31 -0
  71. package/dist/data/utilities/joinKey.min.js +1 -0
  72. package/dist/data/utilities/keyIndexFiles.d.ts +16 -0
  73. package/dist/data/utilities/keyIndexFiles.js +60 -0
  74. package/dist/data/utilities/keyIndexFiles.min.js +1 -0
  75. package/dist/data/utilities/recordExists.js +2 -7
  76. package/dist/data/utilities/recordExists.min.js +1 -1
  77. package/dist/data/utilities/registerRecord.js +4 -10
  78. package/dist/data/utilities/registerRecord.min.js +1 -1
  79. package/dist/data/utilities/removeFromIndex.js +4 -10
  80. package/dist/data/utilities/removeFromIndex.min.js +1 -1
  81. package/dist/data/utilities/retrieveFile.d.ts +5 -0
  82. package/dist/data/utilities/retrieveFile.js +7 -16
  83. package/dist/data/utilities/retrieveFile.min.js +1 -1
  84. package/dist/data/utilities/rowLookup.d.ts +38 -0
  85. package/dist/data/utilities/rowLookup.js +99 -0
  86. package/dist/data/utilities/rowLookup.min.js +1 -0
  87. package/dist/data/utilities/runQuery.js +1 -2
  88. package/dist/data/utilities/runQuery.min.js +1 -1
  89. package/dist/data/utilities/semiJoin.d.ts +27 -0
  90. package/dist/data/utilities/semiJoin.js +97 -0
  91. package/dist/data/utilities/semiJoin.min.js +1 -0
  92. package/dist/data/utilities/updateIndex.js +5 -14
  93. package/dist/data/utilities/updateIndex.min.js +1 -1
  94. package/package.json +4 -2
  95. package/dist/data/utilities/getJoinIndexedList.d.ts +0 -3
  96. package/dist/data/utilities/getJoinIndexedList.js +0 -76
  97. package/dist/data/utilities/getJoinIndexedList.min.js +0 -1
  98. package/dist/data/utilities/getMatchingIndexes.d.ts +0 -2
  99. package/dist/data/utilities/getMatchingIndexes.js +0 -28
  100. package/dist/data/utilities/getMatchingIndexes.min.js +0 -1
  101. package/dist/data/utilities/matchIndexedJoins.d.ts +0 -2
  102. package/dist/data/utilities/matchIndexedJoins.js +0 -63
  103. package/dist/data/utilities/matchIndexedJoins.min.js +0 -1
  104. package/dist/data/utilities/restrictIndexedList.d.ts +0 -2
  105. package/dist/data/utilities/restrictIndexedList.js +0 -45
  106. package/dist/data/utilities/restrictIndexedList.min.js +0 -1
  107. package/dist/data/utilities/useJoinClause.d.ts +0 -6
  108. package/dist/data/utilities/useJoinClause.js +0 -57
  109. package/dist/data/utilities/useJoinClause.min.js +0 -1
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.sameValue = exports.compareAs = void 0;
6
+ exports.sameValue = exports.compareAs = exports.comparableTypes = void 0;
7
7
  require("core-js/modules/es.array.includes.js");
8
8
  /**
9
9
  * Normalize a value to a field's declared type for an equality comparison - never written back,
@@ -39,7 +39,7 @@ const compareAs = (type, value) => {
39
39
  }
40
40
  };
41
41
  exports.compareAs = compareAs;
42
- const comparableTypes = ['string', 'int', 'boolean'];
42
+ const comparableTypes = exports.comparableTypes = ['string', 'int', 'boolean'];
43
43
  /**
44
44
  * Whether two values are equal for a field of the given declared type: both are normalized to
45
45
  * that type (see compareAs) and compared strictly. A field with no declared type, or one that
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.sameValue=exports.compareAs=void 0,require("core-js/modules/es.array.includes.js");const compareAs=(e,r)=>{if(null==r)return r;switch(e){case"string":return"object"==typeof r?r:String(r);case"int":{const e=Number(r);return Number.isNaN(e)?r:e}case"boolean":return"true"===r||"false"!==r&&r;default:return r}};exports.compareAs=compareAs;const comparableTypes=["string","int","boolean"],sameValue=(e,r,s)=>comparableTypes.includes(e)?compareAs(e,r)===compareAs(e,s):r==s;exports.sameValue=sameValue;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.sameValue=exports.compareAs=exports.comparableTypes=void 0,require("core-js/modules/es.array.includes.js");const compareAs=(e,r)=>{if(null==r)return r;switch(e){case"string":return"object"==typeof r?r:String(r);case"int":{const e=Number(r);return Number.isNaN(e)?r:e}case"boolean":return"true"===r||"false"!==r&&r;default:return r}};exports.compareAs=compareAs;const comparableTypes=exports.comparableTypes=["string","int","boolean"],sameValue=(e,r,s)=>comparableTypes.includes(e)?compareAs(e,r)===compareAs(e,s):r==s;exports.sameValue=sameValue;
@@ -8,6 +8,8 @@
8
8
  * Only the public functions (query, create, drop, describe) take the lock; what they call inside doesn't take it
9
9
  * again, so it can't deadlock. In the browser nothing can be written, so tasks just run.
10
10
  *
11
+ * Each task also runs with a read cache (see withReadCache): the files it reads are read once for the whole call.
12
+ *
11
13
  * The queue is per folder (`database/` and `./database` share one). Every step of a task reads databasePath when it
12
14
  * runs, so configure() refuses to change it while tasks are queued or running (see trackDatabaseCall).
13
15
  * @param task
@@ -20,6 +20,7 @@ require("core-js/modules/esnext.map.some.js");
20
20
  require("core-js/modules/esnext.map.update.js");
21
21
  var jsEnv = _interopRequireWildcard(require("browser-or-node"));
22
22
  var _config = require("./config");
23
+ var _storage = require("../storage");
23
24
  var e;
24
25
  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; }
25
26
  const queues = new Map();
@@ -33,13 +34,15 @@ const queues = new Map();
33
34
  * Only the public functions (query, create, drop, describe) take the lock; what they call inside doesn't take it
34
35
  * again, so it can't deadlock. In the browser nothing can be written, so tasks just run.
35
36
  *
37
+ * Each task also runs with a read cache (see withReadCache): the files it reads are read once for the whole call.
38
+ *
36
39
  * The queue is per folder (`database/` and `./database` share one). Every step of a task reads databasePath when it
37
40
  * runs, so configure() refuses to change it while tasks are queued or running (see trackDatabaseCall).
38
41
  * @param task
39
42
  */
40
43
  const withDatabaseLock = async task => {
41
44
  if (!jsEnv.isNode) {
42
- return task();
45
+ return (0, _storage.withReadCache)(task);
43
46
  }
44
47
  const database = (0, _config.resolveDatabasePath)((0, _config.getSetting)('databasePath', 'database/'));
45
48
  const ended = (0, _config.trackDatabaseCall)();
@@ -52,7 +55,7 @@ const withDatabaseLock = async task => {
52
55
  queues.set(database, queued);
53
56
  await previous;
54
57
  try {
55
- return await task();
58
+ return await (0, _storage.withReadCache)(task);
56
59
  } finally {
57
60
  ended();
58
61
  release();
@@ -1 +1 @@
1
- "use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.withDatabaseLock=void 0,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");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config");function _interopRequireWildcard(s,r){if(!r&&s&&s.__esModule)return s;var t,a,o=Object.defineProperty,u={__proto__:null,default:s};if(Object(s)!==s)return u;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(s))return e.get(s);e.set(s,u)}for(a in s)"default"!==a&&{}.hasOwnProperty.call(s,a)&&((t=o&&Object.getOwnPropertyDescriptor(s,a))&&(t.get||t.set)?o(u,a,t):u[a]=s[a]);return u}const queues=new Map,withDatabaseLock=async e=>{if(!jsEnv.isNode)return e();const s=(0,_config.resolveDatabasePath)((0,_config.getSetting)("databasePath","database/")),r=(0,_config.trackDatabaseCall)(),t=queues.get(s)||Promise.resolve();let a;const o=new Promise((e=>{a=e})),u=t.then((()=>o));queues.set(s,u),await t;try{return await e()}finally{r(),a(),queues.get(s)===u&&queues.delete(s)}};exports.withDatabaseLock=withDatabaseLock;
1
+ "use strict";require("core-js/modules/esnext.weak-map.delete-all.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.withDatabaseLock=void 0,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");var e,jsEnv=_interopRequireWildcard(require("browser-or-node")),_config=require("./config"),_storage=require("../storage");function _interopRequireWildcard(s,r){if(!r&&s&&s.__esModule)return s;var t,a,o=Object.defineProperty,u={__proto__:null,default:s};if(Object(s)!==s)return u;if(e||"function"!=typeof WeakMap||(e=new WeakMap),e){if(e.has(s))return e.get(s);e.set(s,u)}for(a in s)"default"!==a&&{}.hasOwnProperty.call(s,a)&&((t=o&&Object.getOwnPropertyDescriptor(s,a))&&(t.get||t.set)?o(u,a,t):u[a]=s[a]);return u}const queues=new Map,withDatabaseLock=async e=>{if(!jsEnv.isNode)return(0,_storage.withReadCache)(e);const s=(0,_config.resolveDatabasePath)((0,_config.getSetting)("databasePath","database/")),r=(0,_config.trackDatabaseCall)(),t=queues.get(s)||Promise.resolve();let a;const o=new Promise((e=>{a=e})),u=t.then((()=>o));queues.set(s,u),await t;try{return await(0,_storage.withReadCache)(e)}finally{r(),a(),queues.get(s)===u&&queues.delete(s)}};exports.withDatabaseLock=withDatabaseLock;
@@ -4,31 +4,25 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.deregisterRecord = void 0;
7
- require("core-js/modules/es.json.stringify.js");
8
7
  require("core-js/modules/esnext.iterator.constructor.js");
9
8
  require("core-js/modules/esnext.iterator.filter.js");
10
- var _config = require("./config");
11
- const {
12
- readFile,
13
- writeFile
14
- } = require('fs/promises');
9
+ var _storage = require("../storage");
15
10
  /**
16
11
  * Remove a record's filename from the __RECORDS registry. A missing registry file is left
17
12
  * untouched rather than created, since there's nothing to remove from it.
18
13
  * @param recordName
19
14
  */
20
15
  const deregisterRecord = async recordName => {
21
- const databasePath = (0, _config.getSetting)('databasePath', 'database/');
22
- const registryPath = `${databasePath}__RECORDS.json`;
16
+ const registryPath = '__RECORDS.json';
23
17
  let registry;
24
18
  try {
25
- registry = JSON.parse(await readFile(registryPath, 'utf8'));
19
+ registry = await (0, _storage.readJson)(registryPath);
26
20
  } catch (err) {
27
21
  return null;
28
22
  }
29
23
  const fileName = `${recordName}.json`;
30
24
  registry.entries = registry.entries.filter(entry => entry !== fileName);
31
- await writeFile(registryPath, JSON.stringify(registry, null, 2));
25
+ await (0, _storage.writeJson)(registryPath, registry);
32
26
  return registry;
33
27
  };
34
28
  exports.deregisterRecord = deregisterRecord;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deregisterRecord=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");var _config=require("./config");const{readFile:readFile,writeFile:writeFile}=require("fs/promises"),deregisterRecord=async e=>{const r=`${(0,_config.getSetting)("databasePath","database/")}__RECORDS.json`;let t;try{t=JSON.parse(await readFile(r,"utf8"))}catch(e){return null}const s=`${e}.json`;return t.entries=t.entries.filter((e=>e!==s)),await writeFile(r,JSON.stringify(t,null,2)),t};exports.deregisterRecord=deregisterRecord;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deregisterRecord=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js");var _storage=require("../storage");const deregisterRecord=async e=>{const r="__RECORDS.json";let t;try{t=await(0,_storage.readJson)(r)}catch(e){return null}const s=`${e}.json`;return t.entries=t.entries.filter((e=>e!==s)),await(0,_storage.writeJson)(r,t),t};exports.deregisterRecord=deregisterRecord;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Whether any row of `entity` has `property` = `value` (compared by the field's declared type, as where does: a null
3
+ * equals nothing), answered from the index of a single-field key on the field: one file instead of every row.
4
+ *
5
+ * Undefined when there is no such index, or its file can't be read or parsed (a key added to a record by hand, a file
6
+ * edited badly): the caller then reads the rows, which are the truth, as these checks always did. A record with no rows
7
+ * has none, whatever its index says.
8
+ * @param entity
9
+ * @param property
10
+ * @param value
11
+ */
12
+ export declare const indexHas: (entity: string, property: string, value: any) => Promise<boolean | undefined>;
13
+ //# sourceMappingURL=indexHas.d.ts.map
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.indexHas = void 0;
7
+ require("core-js/modules/esnext.iterator.constructor.js");
8
+ require("core-js/modules/esnext.iterator.find.js");
9
+ require("core-js/modules/esnext.iterator.some.js");
10
+ var _storage = require("../storage");
11
+ var _where = require("../queries/where");
12
+ var _retrieveRecord = require("./retrieveRecord");
13
+ var _isSingleFieldKey = require("./isSingleFieldKey");
14
+ var _fieldType = require("./fieldType");
15
+ /**
16
+ * Whether any row of `entity` has `property` = `value` (compared by the field's declared type, as where does: a null
17
+ * equals nothing), answered from the index of a single-field key on the field: one file instead of every row.
18
+ *
19
+ * Undefined when there is no such index, or its file can't be read or parsed (a key added to a record by hand, a file
20
+ * edited badly): the caller then reads the rows, which are the truth, as these checks always did. A record with no rows
21
+ * has none, whatever its index says.
22
+ * @param entity
23
+ * @param property
24
+ * @param value
25
+ */
26
+ const indexHas = async (entity, property, value) => {
27
+ const record = await (0, _retrieveRecord.retrieveRecord)(entity);
28
+ const key = record.keys.find(key => (0, _isSingleFieldKey.isSingleFieldKey)(key, property) && key.lookup);
29
+ if (!key) {
30
+ return undefined;
31
+ }
32
+ if (!(record.entries || []).length) {
33
+ return false;
34
+ }
35
+ let index;
36
+ try {
37
+ index = await (0, _storage.readJson)(`__indexes/${record.path}/${key.lookup}`);
38
+ } catch (err) {
39
+ return undefined;
40
+ }
41
+ return (0, _where.where)(index, {
42
+ property: 'value',
43
+ comparator: '=',
44
+ value,
45
+ type: (0, _fieldType.fieldType)(record, property)
46
+ }).some(entry => Array.isArray(entry.record) && entry.record.length > 0);
47
+ };
48
+ exports.indexHas = indexHas;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.indexHas=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.some.js");var _storage=require("../storage"),_where=require("../queries/where"),_retrieveRecord=require("./retrieveRecord"),_isSingleFieldKey=require("./isSingleFieldKey"),_fieldType=require("./fieldType");const indexHas=async(e,r,i)=>{const t=await(0,_retrieveRecord.retrieveRecord)(e),s=t.keys.find((e=>(0,_isSingleFieldKey.isSingleFieldKey)(e,r)&&e.lookup));if(!s)return;if(!(t.entries||[]).length)return!1;let o;try{o=await(0,_storage.readJson)(`__indexes/${t.path}/${s.lookup}`)}catch(e){return}return(0,_where.where)(o,{property:"value",comparator:"=",value:i,type:(0,_fieldType.fieldType)(t,r)}).some((e=>Array.isArray(e.record)&&e.record.length>0))};exports.indexHas=indexHas;
@@ -0,0 +1,29 @@
1
+ import { JoinSide } from './semiJoin';
2
+ /**
3
+ * One `on` clause, with each side's record, field and the declared type it's compared by.
4
+ */
5
+ export type JoinStep = {
6
+ entityA: string;
7
+ propertyA: string;
8
+ typeA: string | undefined;
9
+ comparator: string;
10
+ entityB: string;
11
+ propertyB: string;
12
+ typeB: string | undefined;
13
+ };
14
+ /**
15
+ * The rows a join reads for each record in it, once for the whole join (every row's join then works from them):
16
+ * - the queried record: its rows (already read, or narrowed by the where clause)
17
+ * - the joined record when the where clause already narrowed it: those rows
18
+ * - a record joined by `=` to one already read, through an index on its field and with both fields of one type: only
19
+ * the rows whose value one of those rows has (the others can't match any row's join, and the order is the record's
20
+ * own, so the join's result is the same as from all of them)
21
+ * - any other: all its rows, kept on the query's data as before (merge reads them from there)
22
+ * @param entity
23
+ * @param joinEntity
24
+ * @param dataSets
25
+ * @param steps
26
+ * @param joinAlreadyResolved
27
+ */
28
+ export declare const joinBases: (entity: string, joinEntity: string, dataSets: Object, steps: JoinStep[], joinAlreadyResolved: boolean) => Promise<Map<string, JoinSide>>;
29
+ //# sourceMappingURL=joinBases.d.ts.map
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.joinBases = void 0;
7
+ require("core-js/modules/esnext.iterator.constructor.js");
8
+ require("core-js/modules/esnext.iterator.filter.js");
9
+ require("core-js/modules/esnext.iterator.for-each.js");
10
+ require("core-js/modules/esnext.iterator.map.js");
11
+ require("core-js/modules/esnext.map.delete-all.js");
12
+ require("core-js/modules/esnext.map.every.js");
13
+ require("core-js/modules/esnext.map.filter.js");
14
+ require("core-js/modules/esnext.map.find.js");
15
+ require("core-js/modules/esnext.map.find-key.js");
16
+ require("core-js/modules/esnext.map.includes.js");
17
+ require("core-js/modules/esnext.map.key-of.js");
18
+ require("core-js/modules/esnext.map.map-keys.js");
19
+ require("core-js/modules/esnext.map.map-values.js");
20
+ require("core-js/modules/esnext.map.merge.js");
21
+ require("core-js/modules/esnext.map.reduce.js");
22
+ require("core-js/modules/esnext.map.some.js");
23
+ require("core-js/modules/esnext.map.update.js");
24
+ require("core-js/modules/esnext.set.add-all.js");
25
+ require("core-js/modules/esnext.set.delete-all.js");
26
+ require("core-js/modules/esnext.set.difference.js");
27
+ require("core-js/modules/esnext.set.every.js");
28
+ require("core-js/modules/esnext.set.filter.js");
29
+ require("core-js/modules/esnext.set.find.js");
30
+ require("core-js/modules/esnext.set.intersection.js");
31
+ require("core-js/modules/esnext.set.is-disjoint-from.js");
32
+ require("core-js/modules/esnext.set.is-subset-of.js");
33
+ require("core-js/modules/esnext.set.is-superset-of.js");
34
+ require("core-js/modules/esnext.set.join.js");
35
+ require("core-js/modules/esnext.set.map.js");
36
+ require("core-js/modules/esnext.set.reduce.js");
37
+ require("core-js/modules/esnext.set.some.js");
38
+ require("core-js/modules/esnext.set.symmetric-difference.js");
39
+ require("core-js/modules/esnext.set.union.js");
40
+ var _readEntity = require("../queries/readEntity");
41
+ var _retrieveRecord = require("./retrieveRecord");
42
+ var _retrieveFile = require("./retrieveFile");
43
+ var _retrieveIndexes = require("./retrieveIndexes");
44
+ var _joinKey = require("./joinKey");
45
+ var _rowLookup = require("./rowLookup");
46
+ /**
47
+ * The rows of `entity` whose `property` equals that field of at least one of `others`, found through the field's index
48
+ * (reading only those rows' files), or undefined when the field has no single-field index.
49
+ * @param entity
50
+ * @param property
51
+ * @param type
52
+ * @param others
53
+ * @param otherProperty
54
+ */
55
+ const indexedRows = async (entity, property, type, others, otherProperty) => {
56
+ const index = (await (0, _retrieveIndexes.retrieveIndexes)(entity, [property], {}))[property];
57
+ if (!index) {
58
+ return undefined;
59
+ }
60
+ const wanted = new Set(others.map(row => (0, _joinKey.joinKey)(type, row[otherProperty])).filter(key => typeof key !== 'undefined'));
61
+ const files = new Set();
62
+ for (const entry of index) {
63
+ if (wanted.has((0, _joinKey.joinKey)(type, entry.value))) {
64
+ entry.record.forEach(file => files.add(file));
65
+ }
66
+ }
67
+ // In the record's own order, as a full read gives them
68
+ const record = await (0, _retrieveRecord.retrieveRecord)(entity);
69
+ const rows = [];
70
+ for (const file of record.entries.filter(entry => files.has(entry))) {
71
+ const data = await (0, _retrieveFile.retrieveFile)(`${record.path}/${file}`).catch(err => console.error(err));
72
+ if (!data) {
73
+ throw new Error(`Could not read entity ${file}`);
74
+ }
75
+ rows.push(data);
76
+ }
77
+ return rows;
78
+ };
79
+ /**
80
+ * The rows a join reads for each record in it, once for the whole join (every row's join then works from them):
81
+ * - the queried record: its rows (already read, or narrowed by the where clause)
82
+ * - the joined record when the where clause already narrowed it: those rows
83
+ * - a record joined by `=` to one already read, through an index on its field and with both fields of one type: only
84
+ * the rows whose value one of those rows has (the others can't match any row's join, and the order is the record's
85
+ * own, so the join's result is the same as from all of them)
86
+ * - any other: all its rows, kept on the query's data as before (merge reads them from there)
87
+ * @param entity
88
+ * @param joinEntity
89
+ * @param dataSets
90
+ * @param steps
91
+ * @param joinAlreadyResolved
92
+ */
93
+ const joinBases = async (entity, joinEntity, dataSets, steps, joinAlreadyResolved) => {
94
+ const bases = new Map();
95
+ const keep = (name, rows) => bases.set(name, {
96
+ rows,
97
+ lookups: new _rowLookup.RowLookups(rows)
98
+ });
99
+ keep(entity, dataSets[entity]);
100
+ if (joinAlreadyResolved) {
101
+ keep(joinEntity, dataSets[joinEntity]);
102
+ }
103
+ const allRows = async name => (await (0, _readEntity.readEntity)(name, dataSets))[name];
104
+ for (const step of steps) {
105
+ const sides = [{
106
+ name: step.entityA,
107
+ property: step.propertyA,
108
+ other: step.entityB,
109
+ otherProperty: step.propertyB
110
+ }, {
111
+ name: step.entityB,
112
+ property: step.propertyB,
113
+ other: step.entityA,
114
+ otherProperty: step.propertyA
115
+ }];
116
+ for (const {
117
+ name,
118
+ property,
119
+ other,
120
+ otherProperty
121
+ } of sides) {
122
+ if (bases.has(name)) {
123
+ continue;
124
+ }
125
+ // Fields of two types could disagree on which rows match (each side compares by its own), so only one type
126
+ const narrowable = step.comparator === '=' && step.typeA === step.typeB && (0, _joinKey.isKeyedType)(step.typeA) && bases.has(other);
127
+ const rows = narrowable ? await indexedRows(name, property, step.typeA, bases.get(other).rows, otherProperty) : undefined;
128
+ keep(name, rows ?? (await allRows(name)));
129
+ }
130
+ }
131
+ if (!bases.has(joinEntity)) {
132
+ keep(joinEntity, await allRows(joinEntity));
133
+ }
134
+ return bases;
135
+ };
136
+ exports.joinBases = joinBases;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.joinBases=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.iterator.map.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 _readEntity=require("../queries/readEntity"),_retrieveRecord=require("./retrieveRecord"),_retrieveFile=require("./retrieveFile"),_retrieveIndexes=require("./retrieveIndexes"),_joinKey=require("./joinKey"),_rowLookup=require("./rowLookup");const indexedRows=async(e,r,s,o,t)=>{const i=(await(0,_retrieveIndexes.retrieveIndexes)(e,[r],{}))[r];if(!i)return;const n=new Set(o.map((e=>(0,_joinKey.joinKey)(s,e[t]))).filter((e=>void 0!==e))),u=new Set;for(const e of i)n.has((0,_joinKey.joinKey)(s,e.value))&&e.record.forEach((e=>u.add(e)));const j=await(0,_retrieveRecord.retrieveRecord)(e),d=[];for(const e of j.entries.filter((e=>u.has(e)))){const r=await(0,_retrieveFile.retrieveFile)(`${j.path}/${e}`).catch((e=>console.error(e)));if(!r)throw new Error(`Could not read entity ${e}`);d.push(r)}return d},joinBases=async(e,r,s,o,t)=>{const i=new Map,n=(e,r)=>i.set(e,{rows:r,lookups:new _rowLookup.RowLookups(r)});n(e,s[e]),t&&n(r,s[r]);const u=async e=>(await(0,_readEntity.readEntity)(e,s))[e];for(const e of o){const r=[{name:e.entityA,property:e.propertyA,other:e.entityB,otherProperty:e.propertyB},{name:e.entityB,property:e.propertyB,other:e.entityA,otherProperty:e.propertyA}];for(const{name:s,property:o,other:t,otherProperty:j}of r){if(i.has(s))continue;n(s,("="===e.comparator&&e.typeA===e.typeB&&(0,_joinKey.isKeyedType)(e.typeA)&&i.has(t)?await indexedRows(s,o,e.typeA,i.get(t).rows,j):void 0)??await u(s))}}return i.has(r)||n(r,await u(r)),i};exports.joinBases=joinBases;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * The key a value is looked up by when joining on `=` for a field of the given declared type: two values are equal for
3
+ * that field (sameValue) exactly when their keys are the same Map key. Undefined for a null or missing value, which
4
+ * equals nothing (as in where).
5
+ *
6
+ * Only for the types sameValue normalizes (see isKeyedType); any other type compares loosely (`==`), which no Map key
7
+ * can express, so those joins keep comparing row by row.
8
+ * @param type
9
+ * @param value
10
+ */
11
+ export declare const joinKey: (type: string | undefined, value: any) => any;
12
+ /**
13
+ * Whether `=` on a field of this declared type can be answered by joinKey lookups.
14
+ * @param type
15
+ */
16
+ export declare const isKeyedType: (type: string | undefined) => boolean;
17
+ //# sourceMappingURL=joinKey.d.ts.map
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.joinKey = exports.isKeyedType = void 0;
7
+ require("core-js/modules/es.array.includes.js");
8
+ var _compareAs = require("./compareAs");
9
+ /**
10
+ * The key a value is looked up by when joining on `=` for a field of the given declared type: two values are equal for
11
+ * that field (sameValue) exactly when their keys are the same Map key. Undefined for a null or missing value, which
12
+ * equals nothing (as in where).
13
+ *
14
+ * Only for the types sameValue normalizes (see isKeyedType); any other type compares loosely (`==`), which no Map key
15
+ * can express, so those joins keep comparing row by row.
16
+ * @param type
17
+ * @param value
18
+ */
19
+ const joinKey = (type, value) => {
20
+ if (value === null || typeof value === 'undefined') {
21
+ return undefined;
22
+ }
23
+ return (0, _compareAs.compareAs)(type, value);
24
+ };
25
+ /**
26
+ * Whether `=` on a field of this declared type can be answered by joinKey lookups.
27
+ * @param type
28
+ */
29
+ exports.joinKey = joinKey;
30
+ const isKeyedType = type => _compareAs.comparableTypes.includes(type);
31
+ exports.isKeyedType = isKeyedType;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.joinKey=exports.isKeyedType=void 0,require("core-js/modules/es.array.includes.js");var _compareAs=require("./compareAs");const joinKey=(e,s)=>{if(null!=s)return(0,_compareAs.compareAs)(e,s)};exports.joinKey=joinKey;const isKeyedType=e=>_compareAs.comparableTypes.includes(e);exports.isKeyedType=isKeyedType;
@@ -0,0 +1,16 @@
1
+ import { recordDefinition } from '../introspect/definitions/record';
2
+ import { keyDefinition } from '../introspect/definitions/key';
3
+ /**
4
+ * The entry files a key's index lists for the values `matches` accepts, in the record's own order (the order its rows
5
+ * are read in). A composite key's index holds its combined value (see computeKeyValue), so `matches` is given that.
6
+ *
7
+ * Undefined when the key has no index, or its file can't be read or parsed: the caller then looks through every row.
8
+ * The files are candidates: callers read each one and check its value, and look through the rows for any value the
9
+ * index didn't lead to, so an index that's out of step with the rows costs time, not a wrong result (for primary
10
+ * key values, which inserts and updates keep unique; see removeMatchingEntries for a hand-edited exception).
11
+ * @param record
12
+ * @param key
13
+ * @param matches
14
+ */
15
+ export declare const keyIndexFiles: (record: recordDefinition, key: keyDefinition, matches: (value: any) => boolean) => Promise<string[] | undefined>;
16
+ //# sourceMappingURL=keyIndexFiles.d.ts.map
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.keyIndexFiles = void 0;
7
+ require("core-js/modules/esnext.iterator.constructor.js");
8
+ require("core-js/modules/esnext.iterator.filter.js");
9
+ require("core-js/modules/esnext.iterator.for-each.js");
10
+ require("core-js/modules/esnext.set.add-all.js");
11
+ require("core-js/modules/esnext.set.delete-all.js");
12
+ require("core-js/modules/esnext.set.difference.js");
13
+ require("core-js/modules/esnext.set.every.js");
14
+ require("core-js/modules/esnext.set.filter.js");
15
+ require("core-js/modules/esnext.set.find.js");
16
+ require("core-js/modules/esnext.set.intersection.js");
17
+ require("core-js/modules/esnext.set.is-disjoint-from.js");
18
+ require("core-js/modules/esnext.set.is-subset-of.js");
19
+ require("core-js/modules/esnext.set.is-superset-of.js");
20
+ require("core-js/modules/esnext.set.join.js");
21
+ require("core-js/modules/esnext.set.map.js");
22
+ require("core-js/modules/esnext.set.reduce.js");
23
+ require("core-js/modules/esnext.set.some.js");
24
+ require("core-js/modules/esnext.set.symmetric-difference.js");
25
+ require("core-js/modules/esnext.set.union.js");
26
+ var _storage = require("../storage");
27
+ /**
28
+ * The entry files a key's index lists for the values `matches` accepts, in the record's own order (the order its rows
29
+ * are read in). A composite key's index holds its combined value (see computeKeyValue), so `matches` is given that.
30
+ *
31
+ * Undefined when the key has no index, or its file can't be read or parsed: the caller then looks through every row.
32
+ * The files are candidates: callers read each one and check its value, and look through the rows for any value the
33
+ * index didn't lead to, so an index that's out of step with the rows costs time, not a wrong result (for primary
34
+ * key values, which inserts and updates keep unique; see removeMatchingEntries for a hand-edited exception).
35
+ * @param record
36
+ * @param key
37
+ * @param matches
38
+ */
39
+ const keyIndexFiles = async (record, key, matches) => {
40
+ if (!key.lookup) {
41
+ return undefined;
42
+ }
43
+ if (!(record.entries || []).length) {
44
+ return [];
45
+ }
46
+ let index;
47
+ try {
48
+ index = await (0, _storage.readJson)(`__indexes/${record.path}/${key.lookup}`);
49
+ } catch (err) {
50
+ return undefined;
51
+ }
52
+ const files = new Set();
53
+ for (const entry of Array.isArray(index) ? index : []) {
54
+ if (Array.isArray(entry.record) && matches(entry.value)) {
55
+ entry.record.forEach(file => files.add(file));
56
+ }
57
+ }
58
+ return record.entries.filter(file => files.has(file));
59
+ };
60
+ exports.keyIndexFiles = keyIndexFiles;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyIndexFiles=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.for-each.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 _storage=require("../storage");const keyIndexFiles=async(e,s,r)=>{if(!s.lookup)return;if(!(e.entries||[]).length)return[];let t;try{t=await(0,_storage.readJson)(`__indexes/${e.path}/${s.lookup}`)}catch(e){return}const o=new Set;for(const e of Array.isArray(t)?t:[])Array.isArray(e.record)&&r(e.value)&&e.record.forEach((e=>o.add(e)));return e.entries.filter((e=>o.has(e)))};exports.keyIndexFiles=keyIndexFiles;
@@ -4,15 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.recordExists = void 0;
7
- var _config = require("./config");
7
+ var _storage = require("../storage");
8
8
  /**
9
9
  * Whether a record (its `<name>.json` file) exists in the database. Node only, like the schema statements that use it.
10
10
  * @param entity
11
11
  */
12
- const recordExists = entity => {
13
- const {
14
- existsSync
15
- } = require('fs');
16
- return existsSync(`${(0, _config.getSetting)('databasePath', 'database/')}${entity}.json`);
17
- };
12
+ const recordExists = entity => (0, _storage.fileExists)(`${entity}.json`);
18
13
  exports.recordExists = recordExists;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.recordExists=void 0;var _config=require("./config");const recordExists=e=>{const{existsSync:s}=require("fs");return s(`${(0,_config.getSetting)("databasePath","database/")}${e}.json`)};exports.recordExists=recordExists;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.recordExists=void 0;var _storage=require("../storage");const recordExists=e=>(0,_storage.fileExists)(`${e}.json`);exports.recordExists=recordExists;
@@ -5,12 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.registerRecord = void 0;
7
7
  require("core-js/modules/es.array.includes.js");
8
- require("core-js/modules/es.json.stringify.js");
9
- var _config = require("./config");
10
- const {
11
- readFile,
12
- writeFile
13
- } = require('fs/promises');
8
+ var _storage = require("../storage");
14
9
  /**
15
10
  * __RECORDS is itself an ordinary record - path/definition/keys/entries - whose entries are the
16
11
  * filenames of every other record that has been created. This is the schema it's given the first
@@ -49,11 +44,10 @@ const defaultRegistry = () => ({
49
44
  * @param recordName
50
45
  */
51
46
  const registerRecord = async recordName => {
52
- const databasePath = (0, _config.getSetting)('databasePath', 'database/');
53
- const registryPath = `${databasePath}__RECORDS.json`;
47
+ const registryPath = '__RECORDS.json';
54
48
  let registry;
55
49
  try {
56
- registry = JSON.parse(await readFile(registryPath, 'utf8'));
50
+ registry = await (0, _storage.readJson)(registryPath);
57
51
  } catch (err) {
58
52
  registry = defaultRegistry();
59
53
  }
@@ -61,7 +55,7 @@ const registerRecord = async recordName => {
61
55
  if (!registry.entries.includes(fileName)) {
62
56
  registry.entries.push(fileName);
63
57
  }
64
- await writeFile(registryPath, JSON.stringify(registry, null, 2));
58
+ await (0, _storage.writeJson)(registryPath, registry);
65
59
  return registry;
66
60
  };
67
61
  exports.registerRecord = registerRecord;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerRecord=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/es.json.stringify.js");var _config=require("./config");const{readFile:readFile,writeFile:writeFile}=require("fs/promises"),defaultRegistry=()=>({path:"",definition:[{name:"path",type:"string",optional:!1,autoGenerate:!1},{name:"definition",type:"object",optional:!1,autoGenerate:!1},{name:"keys",type:"array",optional:!1,autoGenerate:!1},{name:"entries",type:"array",optional:!1,autoGenerate:!1}],keys:[],entries:[]}),registerRecord=async e=>{const t=`${(0,_config.getSetting)("databasePath","database/")}__RECORDS.json`;let r;try{r=JSON.parse(await readFile(t,"utf8"))}catch(e){r=defaultRegistry()}const i=`${e}.json`;return r.entries.includes(i)||r.entries.push(i),await writeFile(t,JSON.stringify(r,null,2)),r};exports.registerRecord=registerRecord;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.registerRecord=void 0,require("core-js/modules/es.array.includes.js");var _storage=require("../storage");const defaultRegistry=()=>({path:"",definition:[{name:"path",type:"string",optional:!1,autoGenerate:!1},{name:"definition",type:"object",optional:!1,autoGenerate:!1},{name:"keys",type:"array",optional:!1,autoGenerate:!1},{name:"entries",type:"array",optional:!1,autoGenerate:!1}],keys:[],entries:[]}),registerRecord=async e=>{const t="__RECORDS.json";let r;try{r=await(0,_storage.readJson)(t)}catch(e){r=defaultRegistry()}const a=`${e}.json`;return r.entries.includes(a)||r.entries.push(a),await(0,_storage.writeJson)(t,r),r};exports.registerRecord=registerRecord;
@@ -4,16 +4,11 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.removeFromIndex = void 0;
7
- require("core-js/modules/es.json.stringify.js");
8
7
  require("core-js/modules/esnext.iterator.constructor.js");
9
8
  require("core-js/modules/esnext.iterator.filter.js");
10
9
  require("core-js/modules/esnext.iterator.map.js");
11
- var _config = require("./config");
12
10
  var _compareAs = require("./compareAs");
13
- const {
14
- readFile,
15
- writeFile
16
- } = require('fs/promises');
11
+ var _storage = require("../storage");
17
12
  /**
18
13
  * Remove a single entry file from the index that backs one of a record's keys, dropping a value
19
14
  * entirely once its last file is removed. A key with no lookup, or an index file that doesn't
@@ -28,11 +23,10 @@ const removeFromIndex = async (path = '', key = null, value = undefined, fileNam
28
23
  if (!key || !key.lookup) {
29
24
  return null;
30
25
  }
31
- const databasePath = (0, _config.getSetting)('databasePath', 'database/');
32
- const indexPath = `${databasePath}__indexes/${path}/${key.lookup}`;
26
+ const indexPath = `__indexes/${path}/${key.lookup}`;
33
27
  let index = [];
34
28
  try {
35
- index = JSON.parse(await readFile(indexPath, 'utf8'));
29
+ index = await (0, _storage.readJson)(indexPath);
36
30
  } catch (err) {
37
31
  return null;
38
32
  }
@@ -40,7 +34,7 @@ const removeFromIndex = async (path = '', key = null, value = undefined, fileNam
40
34
  value: entry.value,
41
35
  record: entry.record.filter(record => record !== fileName)
42
36
  } : entry).filter(entry => entry.record.length);
43
- await writeFile(indexPath, JSON.stringify(index, null, 2));
37
+ await (0, _storage.writeJson)(indexPath, index);
44
38
  return index;
45
39
  };
46
40
  exports.removeFromIndex = removeFromIndex;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeFromIndex=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.map.js");var _config=require("./config"),_compareAs=require("./compareAs");const{readFile:readFile,writeFile:writeFile}=require("fs/promises"),removeFromIndex=async(e="",r=null,o=void 0,t="",i=void 0)=>{if(!r||!r.lookup)return null;const s=`${(0,_config.getSetting)("databasePath","database/")}__indexes/${e}/${r.lookup}`;let a=[];try{a=JSON.parse(await readFile(s,"utf8"))}catch(e){return null}return a=a.map((e=>(0,_compareAs.sameValue)(i,e.value,o)?{value:e.value,record:e.record.filter((e=>e!==t))}:e)).filter((e=>e.record.length)),await writeFile(s,JSON.stringify(a,null,2)),a};exports.removeFromIndex=removeFromIndex;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.removeFromIndex=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.filter.js"),require("core-js/modules/esnext.iterator.map.js");var _compareAs=require("./compareAs"),_storage=require("../storage");const removeFromIndex=async(e="",r=null,o=void 0,t="",s=void 0)=>{if(!r||!r.lookup)return null;const a=`__indexes/${e}/${r.lookup}`;let u=[];try{u=await(0,_storage.readJson)(a)}catch(e){return null}return u=u.map((e=>(0,_compareAs.sameValue)(s,e.value,o)?{value:e.value,record:e.record.filter((e=>e!==t))}:e)).filter((e=>e.record.length)),await(0,_storage.writeJson)(a,u),u};exports.removeFromIndex=removeFromIndex;
@@ -1,2 +1,7 @@
1
+ /**
2
+ * Read one JSON file of the database (see readJson), logging the underlying error and throwing one that names the file.
3
+ * @param path - A path inside the database, such as `users.json`.
4
+ * @throws {Error} `Could not read <path>` when the file can't be read.
5
+ */
1
6
  export declare const retrieveFile: (path: any) => Promise<any>;
2
7
  //# sourceMappingURL=retrieveFile.d.ts.map