inibase 1.0.0-rc.19 → 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;
@@ -689,19 +689,20 @@ export default class Inibase {
689
689
  throw this.throwError("NO_SCHEMA", tableName);
690
690
  const idFilePath = join(this.folder, this.database, tableName, "id.inib");
691
691
  let [last_line_number, last_id] = (await File.isExists(idFilePath))
692
- ? Object.entries((await File.get(idFilePath, -1, "number", undefined, this.salt))[0])[0]?.map(Number) ?? [0, 0]
692
+ ? Object.entries((await File.get(idFilePath, -1, "number", undefined, this.salt))[0] ??
693
+ {})[0]?.map(Number) ?? [0, 0]
693
694
  : [0, 0];
694
695
  if (Utils.isArrayOfObjects(data))
695
696
  RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
696
697
  id: ++last_id,
697
698
  ...rest,
698
- createdAt: new Date().getTime(),
699
+ createdAt: Date.now(),
699
700
  }));
700
701
  else
701
702
  RETURN = (({ id, updatedAt, createdAt, ...rest }) => ({
702
703
  id: ++last_id,
703
704
  ...rest,
704
- createdAt: new Date().getTime(),
705
+ createdAt: Date.now(),
705
706
  }))(data);
706
707
  if (!RETURN)
707
708
  throw this.throwError("NO_DATA");
@@ -742,11 +743,11 @@ export default class Inibase {
742
743
  const pathesContents = this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
743
744
  ? data.map((item) => ({
744
745
  ...(({ id, ...restOfData }) => restOfData)(item),
745
- updatedAt: new Date().getTime(),
746
+ updatedAt: Date.now(),
746
747
  }))
747
748
  : {
748
749
  ...(({ id, ...restOfData }) => restOfData)(data),
749
- updatedAt: new Date().getTime(),
750
+ updatedAt: Date.now(),
750
751
  });
751
752
  for await (const [path, content] of Object.entries(pathesContents))
752
753
  await File.replace(path, content);
@@ -769,9 +770,9 @@ export default class Inibase {
769
770
  const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
770
771
  ? data.map((item) => ({
771
772
  ...item,
772
- updatedAt: new Date().getTime(),
773
+ updatedAt: Date.now(),
773
774
  }))
774
- : { ...data, updatedAt: new Date().getTime() })).map(([path, content]) => [
775
+ : { ...data, updatedAt: Date.now() })).map(([path, content]) => [
775
776
  path,
776
777
  [...(Array.isArray(where) ? where : [where])].reduce((obj, lineNum, index) => ({
777
778
  ...obj,
@@ -801,11 +802,10 @@ export default class Inibase {
801
802
  if (!(await File.isExists(idFilePath)))
802
803
  throw this.throwError("NO_ITEMS", tableName);
803
804
  if (!where) {
804
- const files = await readdir(join(this.folder, this.database, tableName));
805
- if (files.length) {
806
- 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)
807
808
  await unlink(join(this.folder, this.database, tableName, file));
808
- }
809
809
  return "*";
810
810
  }
811
811
  else if ((Array.isArray(where) &&
@@ -820,13 +820,13 @@ export default class Inibase {
820
820
  else if ((Array.isArray(where) && where.every(Utils.isNumber)) ||
821
821
  Utils.isNumber(where)) {
822
822
  // "where" in this case, is the line(s) number(s) and not id(s)
823
- 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"));
824
824
  if (files.length) {
825
825
  if (!_id)
826
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));
827
827
  if (!_id.length)
828
828
  throw this.throwError("NO_ITEMS", tableName);
829
- for (const file of files.filter((fileName) => fileName.endsWith(".inib")))
829
+ for await (const file of files)
830
830
  await File.remove(join(this.folder, this.database, tableName, file), where);
831
831
  return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
832
832
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.19",
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",