inibase 1.0.0-rc.20 → 1.0.0-rc.21

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 CHANGED
@@ -57,6 +57,19 @@ Become a sponsor and have your company logo here 👉 [GitHub Sponsors](https://
57
57
 
58
58
  To semplify the idea, each database has tables, each table has columns, each column will be stored in a seperated file. When POSTing new data, it will be appended to each columns file as new line. When GETing data, the file will be readed line-by-line so it can handle large data (without consuming a lot of resources)
59
59
 
60
+ ## Benchmark
61
+ ```js
62
+ Bulk
63
+ ┌─────────┬─────────┬─────────┐
64
+ │ 10 │ 100 │ 1000 │
65
+ ┌─────────┼─────────┼─────────┼─────────┤
66
+ │ POST │ '23 ms' │ '20 ms' │ '83 ms' │
67
+ │ GET │ '12 ms' │ '16 ms' │ '45 ms' │
68
+ │ PUT │ '6 ms' │ '4 ms' │ '11 ms' │
69
+ │ DELETE │ '18 ms' │ '21 ms' │ '27 ms' │
70
+ └─────────┴─────────┴─────────┴─────────┘
71
+ ```
72
+
60
73
  ## Examples
61
74
 
62
75
  <details>
package/dist/file.js CHANGED
@@ -118,73 +118,85 @@ export const decode = (input, fieldType, fieldChildrenType, secretKey) => {
118
118
  : input, fieldType, fieldChildrenType, secretKey);
119
119
  };
120
120
  export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, secretKey) => {
121
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
122
- ? fileHandle.readLines({ autoClose: false })
123
- : createInterface({
124
- input: fileHandle.createReadStream({ autoClose: false }),
125
- crlfDelay: Infinity,
126
- });
127
- let lines = new Map(), lineCount = 0;
128
- if (!lineNumbers) {
129
- for await (const line of rl)
130
- lineCount++,
121
+ let fileHandle;
122
+ try {
123
+ fileHandle = await open(filePath, "r");
124
+ const rl = doesSupportReadLines()
125
+ ? fileHandle.readLines()
126
+ : createInterface({
127
+ input: fileHandle.createReadStream(),
128
+ crlfDelay: Infinity,
129
+ });
130
+ let lines = new Map(), lineCount = 0;
131
+ if (!lineNumbers) {
132
+ for await (const line of rl)
133
+ lineCount++,
134
+ lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
135
+ }
136
+ else if (lineNumbers === -1) {
137
+ let lastLine;
138
+ for await (const line of rl)
139
+ lineCount++, (lastLine = line);
140
+ if (lastLine)
141
+ lines.set(lineCount, decode(lastLine, fieldType, fieldChildrenType, secretKey));
142
+ }
143
+ else {
144
+ let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
145
+ for await (const line of rl) {
146
+ lineCount++;
147
+ if (!lineNumbersArray.has(lineCount))
148
+ continue;
131
149
  lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
132
- }
133
- else if (lineNumbers === -1) {
134
- let lastLine;
135
- for await (const line of rl)
136
- lineCount++, (lastLine = line);
137
- if (lastLine)
138
- lines.set(lineCount, decode(lastLine, fieldType, fieldChildrenType, secretKey));
139
- }
140
- else {
141
- let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
142
- for await (const line of rl) {
143
- lineCount++;
144
- if (!lineNumbersArray.has(lineCount))
145
- continue;
146
- lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
147
- lineNumbersArray.delete(lineCount);
148
- if (!lineNumbersArray.size)
149
- break;
150
+ lineNumbersArray.delete(lineCount);
151
+ if (!lineNumbersArray.size)
152
+ break;
153
+ }
150
154
  }
155
+ return [lines.size ? Object.fromEntries(lines) : null, lineCount];
156
+ }
157
+ finally {
158
+ await fileHandle?.close();
151
159
  }
152
- await fileHandle.close();
153
- return [lines.size ? Object.fromEntries(lines) : null, lineCount];
154
160
  };
155
161
  export const replace = async (filePath, replacements) => {
156
162
  if (await isExists(filePath)) {
157
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
158
- ? fileHandle.readLines({ autoClose: false })
159
- : createInterface({
160
- input: fileHandle.createReadStream({ autoClose: false }),
161
- crlfDelay: Infinity,
162
- }), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w+"), writeStream = fileTempHandle.createWriteStream({ autoClose: false });
163
- if (typeof replacements === "object" && !Array.isArray(replacements)) {
164
- if (!(replacements instanceof Map))
165
- replacements = new Map(Object.entries(replacements));
166
- let lineCount = 0;
167
- for await (const line of rl) {
168
- lineCount++;
169
- writeStream.write((replacements.has(lineCount.toString())
170
- ? replacements.get(lineCount.toString())
171
- : line) + "\n");
172
- }
173
- const newLinesNumbers = new Set([...replacements.keys()].filter((num) => num > lineCount));
174
- if (newLinesNumbers.size) {
175
- if (Math.min(...newLinesNumbers) - lineCount - 1 > 1)
176
- writeStream.write("\n".repeat(Math.min(...newLinesNumbers) - lineCount - 1));
177
- for (const newLineNumber of newLinesNumbers)
178
- writeStream.write(replacements.get(newLineNumber.toString()) + "\n");
163
+ const fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`;
164
+ let fileHandle, fileTempHandle, lineCount = 0;
165
+ try {
166
+ fileHandle = await open(filePath, "r");
167
+ fileTempHandle = await open(fileTempPath, "w+");
168
+ const rl = doesSupportReadLines()
169
+ ? fileHandle.readLines()
170
+ : createInterface({
171
+ input: fileHandle.createReadStream(),
172
+ crlfDelay: Infinity,
173
+ }), writeStream = fileTempHandle.createWriteStream();
174
+ if (typeof replacements === "object" && !Array.isArray(replacements)) {
175
+ if (!(replacements instanceof Map))
176
+ replacements = new Map(Object.entries(replacements));
177
+ for await (const line of rl) {
178
+ lineCount++;
179
+ writeStream.write((replacements.has(lineCount.toString())
180
+ ? replacements.get(lineCount.toString())
181
+ : line) + "\n");
182
+ }
183
+ const newLinesNumbers = new Set([...replacements.keys()].filter((num) => num > lineCount));
184
+ if (newLinesNumbers.size) {
185
+ if (Math.min(...newLinesNumbers) - lineCount - 1 > 1)
186
+ writeStream.write("\n".repeat(Math.min(...newLinesNumbers) - lineCount - 1));
187
+ for (const newLineNumber of newLinesNumbers)
188
+ writeStream.write(replacements.get(newLineNumber.toString()) + "\n");
189
+ }
179
190
  }
191
+ else
192
+ for await (const _line of rl)
193
+ writeStream.write(replacements + "\n");
194
+ await rename(fileTempPath, filePath);
195
+ }
196
+ finally {
197
+ await fileHandle?.close();
198
+ await fileTempHandle?.close();
180
199
  }
181
- else
182
- for await (const _line of rl)
183
- writeStream.write(replacements + "\n");
184
- // writeStream.end(async () => await rename(fileTempPath, filePath));
185
- await fileHandle.close();
186
- await fileTempHandle.close();
187
- await rename(fileTempPath, filePath);
188
200
  }
189
201
  else if (typeof replacements === "object" && !Array.isArray(replacements)) {
190
202
  if (!(replacements instanceof Map))
@@ -197,61 +209,78 @@ export const replace = async (filePath, replacements) => {
197
209
  }
198
210
  };
199
211
  export const append = async (filePath, data, startsAt = 1) => {
200
- const doesFileExists = await isExists(filePath);
201
- const fileHandle = await open(filePath, "a"), writeStream = fileHandle.createWriteStream({ autoClose: false });
202
- if (doesFileExists) {
203
- const currentNumberOfLines = await count(filePath);
204
- if (startsAt - currentNumberOfLines - 1 > 0)
205
- writeStream.write("\n".repeat(startsAt - currentNumberOfLines - 1));
206
- if (Array.isArray(data)) {
207
- for (const input of data)
208
- writeStream.write(input + "\n");
212
+ let fileHandle;
213
+ try {
214
+ fileHandle = await open(filePath, "a");
215
+ const doesFileExists = await isExists(filePath);
216
+ const writeStream = fileHandle.createWriteStream();
217
+ if (doesFileExists) {
218
+ const currentNumberOfLines = await count(filePath);
219
+ if (startsAt - currentNumberOfLines - 1 > 0)
220
+ writeStream.write("\n".repeat(startsAt - currentNumberOfLines - 1));
221
+ if (Array.isArray(data)) {
222
+ for (const input of data)
223
+ writeStream.write(input + "\n");
224
+ }
225
+ else
226
+ writeStream.write(data + "\n");
209
227
  }
210
- else
211
- writeStream.write(data + "\n");
212
- }
213
- else {
214
- if (startsAt - 1 > 0)
215
- writeStream.write("\n".repeat(startsAt - 1));
216
- if (Array.isArray(data)) {
217
- for (const input of data)
218
- writeStream.write(input + "\n");
228
+ else {
229
+ if (startsAt - 1 > 0)
230
+ writeStream.write("\n".repeat(startsAt - 1));
231
+ if (Array.isArray(data)) {
232
+ for (const input of data)
233
+ writeStream.write(input + "\n");
234
+ }
235
+ else
236
+ writeStream.write(data + "\n");
219
237
  }
220
- else
221
- writeStream.write(data + "\n");
222
238
  }
223
- await fileHandle.close();
239
+ finally {
240
+ await fileHandle?.close();
241
+ }
224
242
  };
225
243
  export const remove = async (filePath, linesToDelete) => {
226
- let lineCount = 0;
227
- const linesToDeleteArray = new Set(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]), fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
228
- ? fileHandle.readLines({ autoClose: false })
229
- : createInterface({
230
- input: fileHandle.createReadStream({ autoClose: false }),
231
- crlfDelay: Infinity,
232
- }), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w+"), writeStream = fileTempHandle.createWriteStream({ autoClose: false });
233
- for await (const line of rl) {
234
- lineCount++;
235
- if (!linesToDeleteArray.has(lineCount))
236
- writeStream.write(`${line}\n`);
244
+ const fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`;
245
+ let fileHandle, fileTempHandle, lineCount = 0;
246
+ try {
247
+ fileHandle = await open(filePath, "r");
248
+ fileTempHandle = await open(fileTempPath, "w+");
249
+ const linesToDeleteArray = new Set(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]), rl = doesSupportReadLines()
250
+ ? fileHandle.readLines()
251
+ : createInterface({
252
+ input: fileHandle.createReadStream(),
253
+ crlfDelay: Infinity,
254
+ }), writeStream = fileTempHandle.createWriteStream();
255
+ for await (const line of rl) {
256
+ lineCount++;
257
+ if (!linesToDeleteArray.has(lineCount))
258
+ writeStream.write(`${line}\n`);
259
+ }
260
+ await rename(fileTempPath, filePath);
261
+ }
262
+ finally {
263
+ await fileTempHandle?.close();
264
+ await fileHandle?.close();
237
265
  }
238
- // writeStream.end(async () => await rename(fileTempPath, filePath));
239
- await fileHandle.close();
240
- await fileTempHandle.close();
241
- await rename(fileTempPath, filePath);
242
266
  };
243
267
  export const count = async (filePath) => {
244
- let lineCount = 0;
245
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
246
- ? fileHandle.readLines({ autoClose: false })
247
- : createInterface({
248
- input: fileHandle.createReadStream({ autoClose: false }),
249
- crlfDelay: Infinity,
250
- });
251
- for await (const line of rl)
252
- lineCount++;
253
- await fileHandle.close();
254
- return lineCount;
268
+ let fileHandle, lineCount = 0;
269
+ try {
270
+ fileHandle = await open(filePath, "r");
271
+ const rl = doesSupportReadLines()
272
+ ? fileHandle.readLines()
273
+ : createInterface({
274
+ input: fileHandle.createReadStream(),
275
+ crlfDelay: Infinity,
276
+ });
277
+ for await (const line of rl)
278
+ lineCount++;
279
+ return lineCount;
280
+ }
281
+ finally {
282
+ await fileHandle.close();
283
+ }
255
284
  };
256
285
  const handleComparisonOperator = (operator, originalValue, comparedAtValue, fieldType, fieldChildrenType) => {
257
286
  if (Array.isArray(fieldType))
@@ -305,139 +334,155 @@ const handleComparisonOperator = (operator, originalValue, comparedAtValue, fiel
305
334
  }
306
335
  };
307
336
  export const search = async (filePath, operator, comparedAtValue, logicalOperator, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
308
- let RETURN = new Map(), lineCount = 0, foundItems = 0;
309
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
310
- ? fileHandle.readLines({ autoClose: false })
311
- : createInterface({
312
- input: fileHandle.createReadStream({ autoClose: false }),
313
- crlfDelay: Infinity,
314
- });
315
- for await (const line of rl) {
316
- lineCount++;
317
- const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
318
- if ((Array.isArray(operator) &&
319
- Array.isArray(comparedAtValue) &&
320
- ((logicalOperator &&
321
- logicalOperator === "or" &&
322
- operator.some((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType))) ||
323
- operator.every((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType)))) ||
324
- (!Array.isArray(operator) &&
325
- handleComparisonOperator(operator, decodedLine, comparedAtValue, fieldType))) {
326
- foundItems++;
327
- if (offset && foundItems < offset)
328
- continue;
329
- if (limit && foundItems > limit)
330
- if (readWholeFile)
337
+ let fileHandle, RETURN = new Map(), lineCount = 0, foundItems = 0;
338
+ try {
339
+ fileHandle = await open(filePath, "r");
340
+ const rl = doesSupportReadLines()
341
+ ? fileHandle.readLines()
342
+ : createInterface({
343
+ input: fileHandle.createReadStream(),
344
+ crlfDelay: Infinity,
345
+ });
346
+ for await (const line of rl) {
347
+ lineCount++;
348
+ const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
349
+ if ((Array.isArray(operator) &&
350
+ Array.isArray(comparedAtValue) &&
351
+ ((logicalOperator &&
352
+ logicalOperator === "or" &&
353
+ operator.some((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType))) ||
354
+ operator.every((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType)))) ||
355
+ (!Array.isArray(operator) &&
356
+ handleComparisonOperator(operator, decodedLine, comparedAtValue, fieldType))) {
357
+ foundItems++;
358
+ if (offset && foundItems < offset)
331
359
  continue;
332
- else
333
- break;
334
- RETURN.set(lineCount, decodedLine);
360
+ if (limit && foundItems > limit)
361
+ if (readWholeFile)
362
+ continue;
363
+ else
364
+ break;
365
+ RETURN.set(lineCount, decodedLine);
366
+ }
335
367
  }
368
+ return foundItems
369
+ ? [
370
+ Object.fromEntries(RETURN),
371
+ readWholeFile ? foundItems : foundItems - 1,
372
+ ]
373
+ : [null, 0];
374
+ }
375
+ finally {
376
+ await fileHandle?.close();
336
377
  }
337
- await fileHandle.close();
338
- return foundItems
339
- ? [Object.fromEntries(RETURN), readWholeFile ? foundItems : foundItems - 1]
340
- : [null, 0];
341
378
  };
342
379
  export const sum = async (filePath, lineNumbers) => {
343
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
344
- ? fileHandle.readLines({ autoClose: false })
345
- : createInterface({
346
- input: fileHandle.createReadStream({ autoClose: false }),
347
- crlfDelay: Infinity,
348
- });
349
- let sum = 0;
350
- if (lineNumbers) {
351
- let lineCount = 0;
352
- let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
353
- for await (const line of rl) {
354
- lineCount++;
355
- if (!lineNumbersArray.has(lineCount))
356
- continue;
357
- sum += +decode(line, "number");
358
- lineNumbersArray.delete(lineCount);
359
- if (!lineNumbersArray.size)
360
- break;
380
+ let fileHandle, sum = 0;
381
+ try {
382
+ fileHandle = await open(filePath, "r");
383
+ const rl = doesSupportReadLines()
384
+ ? fileHandle.readLines()
385
+ : createInterface({
386
+ input: fileHandle.createReadStream(),
387
+ crlfDelay: Infinity,
388
+ });
389
+ if (lineNumbers) {
390
+ let lineCount = 0;
391
+ let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
392
+ for await (const line of rl) {
393
+ lineCount++;
394
+ if (!lineNumbersArray.has(lineCount))
395
+ continue;
396
+ sum += +decode(line, "number");
397
+ lineNumbersArray.delete(lineCount);
398
+ if (!lineNumbersArray.size)
399
+ break;
400
+ }
361
401
  }
402
+ else
403
+ for await (const line of rl)
404
+ sum += +decode(line, "number");
405
+ return sum;
406
+ }
407
+ finally {
408
+ await fileHandle?.close();
362
409
  }
363
- else
364
- for await (const line of rl)
365
- sum += +decode(line, "number");
366
- return sum;
367
410
  };
368
411
  export const max = async (filePath, lineNumbers) => {
369
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
370
- ? fileHandle.readLines({ autoClose: false })
371
- : createInterface({
372
- input: fileHandle.createReadStream({ autoClose: false }),
373
- crlfDelay: Infinity,
374
- });
375
- let max = 0;
376
- if (lineNumbers) {
377
- let lineCount = 0;
378
- let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
379
- for await (const line of rl) {
380
- lineCount++;
381
- if (!lineNumbersArray.has(lineCount))
382
- continue;
383
- const lineContentNum = +decode(line, "number");
384
- if (lineContentNum > max)
385
- max = lineContentNum;
386
- lineNumbersArray.delete(lineCount);
387
- if (!lineNumbersArray.size)
388
- break;
412
+ let fileHandle, max = 0;
413
+ try {
414
+ fileHandle = await open(filePath, "r");
415
+ const rl = doesSupportReadLines()
416
+ ? fileHandle.readLines()
417
+ : createInterface({
418
+ input: fileHandle.createReadStream(),
419
+ crlfDelay: Infinity,
420
+ });
421
+ if (lineNumbers) {
422
+ let lineCount = 0;
423
+ let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
424
+ for await (const line of rl) {
425
+ lineCount++;
426
+ if (!lineNumbersArray.has(lineCount))
427
+ continue;
428
+ const lineContentNum = +decode(line, "number");
429
+ if (lineContentNum > max)
430
+ max = lineContentNum;
431
+ lineNumbersArray.delete(lineCount);
432
+ if (!lineNumbersArray.size)
433
+ break;
434
+ }
389
435
  }
436
+ else
437
+ for await (const line of rl) {
438
+ const lineContentNum = +decode(line, "number");
439
+ if (lineContentNum > max)
440
+ max = lineContentNum;
441
+ }
442
+ return max;
443
+ }
444
+ finally {
445
+ await fileHandle?.close();
390
446
  }
391
- else
392
- for await (const line of rl) {
393
- const lineContentNum = +decode(line, "number");
394
- if (lineContentNum > max)
395
- max = lineContentNum;
396
- }
397
- return max;
398
447
  };
399
448
  export const min = async (filePath, lineNumbers) => {
400
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
401
- ? fileHandle.readLines({ autoClose: false })
402
- : createInterface({
403
- input: fileHandle.createReadStream({ autoClose: false }),
404
- crlfDelay: Infinity,
405
- });
406
- let min = 0;
407
- if (lineNumbers) {
408
- let lineCount = 0;
409
- let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
410
- for await (const line of rl) {
411
- lineCount++;
412
- if (!lineNumbersArray.has(lineCount))
413
- continue;
414
- const lineContentNum = +decode(line, "number");
415
- if (lineContentNum < min)
416
- min = lineContentNum;
417
- lineNumbersArray.delete(lineCount);
418
- if (!lineNumbersArray.size)
419
- break;
449
+ let fileHandle, min = 0;
450
+ try {
451
+ fileHandle = await open(filePath, "r");
452
+ const rl = doesSupportReadLines()
453
+ ? fileHandle.readLines()
454
+ : createInterface({
455
+ input: fileHandle.createReadStream(),
456
+ crlfDelay: Infinity,
457
+ });
458
+ if (lineNumbers) {
459
+ let lineCount = 0;
460
+ let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
461
+ for await (const line of rl) {
462
+ lineCount++;
463
+ if (!lineNumbersArray.has(lineCount))
464
+ continue;
465
+ const lineContentNum = +decode(line, "number");
466
+ if (lineContentNum < min)
467
+ min = lineContentNum;
468
+ lineNumbersArray.delete(lineCount);
469
+ if (!lineNumbersArray.size)
470
+ break;
471
+ }
420
472
  }
473
+ else
474
+ for await (const line of rl) {
475
+ const lineContentNum = +decode(line, "number");
476
+ if (lineContentNum < min)
477
+ min = lineContentNum;
478
+ }
479
+ return min;
480
+ }
481
+ finally {
482
+ await fileHandle?.close();
421
483
  }
422
- else
423
- for await (const line of rl) {
424
- const lineContentNum = +decode(line, "number");
425
- if (lineContentNum < min)
426
- min = lineContentNum;
427
- }
428
- return min;
429
- };
430
- export const sort = async (filePath, sortDirection, lineNumbers, _lineNumbersPerChunk = 100000) => {
431
- const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
432
- ? fileHandle.readLines({ autoClose: false })
433
- : createInterface({
434
- input: fileHandle.createReadStream({ autoClose: false }),
435
- crlfDelay: Infinity,
436
- });
437
- let lineCount = 0;
438
- for await (const line of rl)
439
- lineCount++;
440
484
  };
485
+ export const sort = async (filePath, sortDirection, lineNumbers, _lineNumbersPerChunk = 100000) => { };
441
486
  export default class File {
442
487
  static get = get;
443
488
  static remove = remove;
package/dist/index.d.ts CHANGED
@@ -84,10 +84,13 @@ export default class Inibase {
84
84
  put(tableName: string, data: Data | Data[], where?: number | string | (number | string)[] | Criteria | undefined, options?: Options | undefined, returnPostedData?: false): Promise<void | null>;
85
85
  put(tableName: string, data: Data, where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnPostedData: true): Promise<Data | null>;
86
86
  put(tableName: string, data: Data[], where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnPostedData: true): Promise<Data[] | null>;
87
- delete(tableName: string, where?: number | string | (number | string)[] | Criteria, _id?: string | string[]): Promise<string | string[] | null>;
87
+ delete(tableName: string, where?: number | string, _id?: string | string[]): Promise<string | null>;
88
+ delete(tableName: string, where?: (number | string)[], _id?: string | string[]): Promise<string[] | null>;
88
89
  sum(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
89
90
  sum(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
90
- max(tableName: string, columns: string | string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
91
- min(tableName: string, columns: string | string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
91
+ max(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
92
+ max(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
93
+ min(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
94
+ min(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
92
95
  }
93
96
  export {};
package/dist/index.js CHANGED
@@ -74,7 +74,7 @@ export default class Inibase {
74
74
  return RETURN;
75
75
  }, replaceOldPathes = Utils.findChangedProperties(schemaToIdsPath(await this.getTableSchema(tableName)), schemaToIdsPath(schema));
76
76
  if (replaceOldPathes)
77
- for (const [oldPath, newPath] of Object.entries(replaceOldPathes))
77
+ for await (const [oldPath, newPath] of Object.entries(replaceOldPathes))
78
78
  if (await File.isExists(join(TablePath, oldPath)))
79
79
  await rename(join(TablePath, oldPath), join(TablePath, newPath));
80
80
  }
@@ -294,7 +294,7 @@ export default class Inibase {
294
294
  async getItemsFromSchema(tableName, schema, linesNumber, options, prefix) {
295
295
  const path = join(this.folder, this.database, tableName);
296
296
  let RETURN = {};
297
- for (const field of schema) {
297
+ for await (const field of schema) {
298
298
  if ((field.type === "array" ||
299
299
  (Array.isArray(field.type) &&
300
300
  field.type.includes("array"))) &&
@@ -382,7 +382,7 @@ export default class Inibase {
382
382
  .map((column) => column.replace(`${field.key}.`, ""));
383
383
  const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, field.type, field.children, this.salt);
384
384
  this.totalItems[tableName + "-" + field.key] = total_lines;
385
- for (const [index, item] of Object.entries(items)) {
385
+ for await (const [index, item] of Object.entries(items)) {
386
386
  if (!RETURN[index])
387
387
  RETURN[index] = {};
388
388
  RETURN[index][field.key] = item
@@ -401,7 +401,7 @@ export default class Inibase {
401
401
  }
402
402
  }
403
403
  else if (field.type === "object") {
404
- for (const [index, item] of Object.entries((await this.getItemsFromSchema(tableName, field.children, linesNumber, options, (prefix ?? "") + field.key + ".")) ?? {})) {
404
+ for await (const [index, item] of Object.entries((await this.getItemsFromSchema(tableName, field.children, linesNumber, options, (prefix ?? "") + field.key + ".")) ?? {})) {
405
405
  if (!RETURN[index])
406
406
  RETURN[index] = {};
407
407
  if (Utils.isObject(item)) {
@@ -424,7 +424,7 @@ export default class Inibase {
424
424
  .map((column) => column.replace(`${field.key}.`, ""));
425
425
  const [items, total_lines] = await File.get(join(path, (prefix ?? "") + field.key + ".inib"), linesNumber, "number", undefined, this.salt);
426
426
  this.totalItems[tableName + "-" + field.key] = total_lines;
427
- for (const [index, item] of Object.entries(items)) {
427
+ for await (const [index, item] of Object.entries(items)) {
428
428
  if (!RETURN[index])
429
429
  RETURN[index] = {};
430
430
  RETURN[index][field.key] = item
@@ -516,7 +516,7 @@ export default class Inibase {
516
516
  if (allTrue === undefined)
517
517
  allTrue = true;
518
518
  let index = -1;
519
- for (const [key, value] of Object.entries(criteria)) {
519
+ for await (const [key, value] of Object.entries(criteria)) {
520
520
  const field = this.getField(key, schema);
521
521
  index++;
522
522
  let searchOperator = undefined, searchComparedAtValue = undefined, searchLogicalOperator = undefined;
@@ -696,13 +696,13 @@ export default class Inibase {
696
696
  RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
697
697
  id: ++last_id,
698
698
  ...rest,
699
- createdAt: new Date().getTime(),
699
+ createdAt: Date.now(),
700
700
  }));
701
701
  else
702
702
  RETURN = (({ id, updatedAt, createdAt, ...rest }) => ({
703
703
  id: ++last_id,
704
704
  ...rest,
705
- createdAt: new Date().getTime(),
705
+ createdAt: Date.now(),
706
706
  }))(data);
707
707
  if (!RETURN)
708
708
  throw this.throwError("NO_DATA");
@@ -743,11 +743,11 @@ export default class Inibase {
743
743
  const pathesContents = this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
744
744
  ? data.map((item) => ({
745
745
  ...(({ id, ...restOfData }) => restOfData)(item),
746
- updatedAt: new Date().getTime(),
746
+ updatedAt: Date.now(),
747
747
  }))
748
748
  : {
749
749
  ...(({ id, ...restOfData }) => restOfData)(data),
750
- updatedAt: new Date().getTime(),
750
+ updatedAt: Date.now(),
751
751
  });
752
752
  for await (const [path, content] of Object.entries(pathesContents))
753
753
  await File.replace(path, content);
@@ -770,9 +770,9 @@ export default class Inibase {
770
770
  const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
771
771
  ? data.map((item) => ({
772
772
  ...item,
773
- updatedAt: new Date().getTime(),
773
+ updatedAt: Date.now(),
774
774
  }))
775
- : { ...data, updatedAt: new Date().getTime() })).map(([path, content]) => [
775
+ : { ...data, updatedAt: Date.now() })).map(([path, content]) => [
776
776
  path,
777
777
  [...(Array.isArray(where) ? where : [where])].reduce((obj, lineNum, index) => ({
778
778
  ...obj,
@@ -802,11 +802,10 @@ export default class Inibase {
802
802
  if (!(await File.isExists(idFilePath)))
803
803
  throw this.throwError("NO_ITEMS", tableName);
804
804
  if (!where) {
805
- const files = await readdir(join(this.folder, this.database, tableName));
806
- if (files.length) {
807
- for (const file in files.filter((fileName) => fileName !== "schema.json"))
805
+ const files = (await readdir(join(this.folder, this.database, tableName)))?.filter((fileName) => fileName.endsWith(".inib"));
806
+ if (files.length)
807
+ for await (const file of files)
808
808
  await unlink(join(this.folder, this.database, tableName, file));
809
- }
810
809
  return "*";
811
810
  }
812
811
  else if ((Array.isArray(where) &&
@@ -821,13 +820,13 @@ export default class Inibase {
821
820
  else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
822
821
  Utils.isNumber(where)) {
823
822
  // "where" in this case, is the line(s) number(s) and not id(s)
824
- const files = await readdir(join(this.folder, this.database, tableName));
823
+ const files = (await readdir(join(this.folder, this.database, tableName)))?.filter((fileName) => fileName.endsWith(".inib"));
825
824
  if (files.length) {
826
825
  if (!_id)
827
826
  _id = Object.values((await File.get(join(this.folder, this.database, tableName, "id.inib"), where, "number", undefined, this.salt))[0] ?? {}).map((id) => UtilsServer.encodeID(Number(id), this.salt));
828
827
  if (!_id.length)
829
828
  throw this.throwError("NO_ITEMS", tableName);
830
- for (const file of files.filter((fileName) => fileName.endsWith(".inib")))
829
+ for await (const file of files)
831
830
  await File.remove(join(this.folder, this.database, tableName, file), where);
832
831
  return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
833
832
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.20",
3
+ "version": "1.0.0-rc.21",
4
4
  "description": "File-based Relational Database for large data",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist",