inibase 1.0.0-rc.60 → 1.0.0-rc.61

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
@@ -64,44 +64,6 @@ const users = await db.get("user", { favoriteFoods: "![]Pizza,Burger" });
64
64
 
65
65
  This structure ensures efficient storage, retrieval, and updates, making our system scalable and high-performing for diverse datasets and applications.
66
66
 
67
- ## Config (.env)
68
-
69
- The `.env` file supports the following parameters
70
-
71
- ```ini
72
- # Don't add this line, it's an auto generated secret key, will be using for encrypting the IDs
73
- INIBASE_SECRET=
74
-
75
- INIBASE_COMPRESSION=false
76
- INIBASE_CACHE=false
77
-
78
- # Prepend new items to the beginning of file
79
- INIBASE_REVERSE=false
80
- ```
81
-
82
- ## Benchmark
83
-
84
- ### Bulk
85
-
86
- | | 10 | 100 | 1000 |
87
- |--------|-----------------|-----------------|-----------------|
88
- | POST | 11 ms (0.65 mb) | 19 ms (1.00 mb) | 85 ms (4.58 mb) |
89
- | GET | 14 ms (2.77 mb) | 12 ms (3.16 mb) | 34 ms (1.38 mb) |
90
- | PUT | 6 ms (1.11 mb) | 5 ms (1.37 mb) | 10 ms (1.12 mb) |
91
- | DELETE | 17 ms (1.68 mb) | 14 ms (5.45 mb) | 25 ms (5.94 mb) |
92
-
93
- ### Single
94
-
95
- | | 10 | 100 | 1000 |
96
- |--------|-------------------|--------------------|--------------------|
97
- | POST | 43 ms (4.70 mb) | 387 ms (6.36 mb) | 5341 ms (24.73 mb) |
98
- | GET | 99 ms (12.51 mb) | 846 ms (30.68 mb) | 7103 ms (30.86 mb) |
99
- | PUT | 33 ms (10.29 mb) | 312 ms (11.06 mb) | 3539 ms (14.87 mb) |
100
- | DELETE | 134 ms (13.50 mb) | 1224 ms (16.57 mb) | 7339 ms (11.46 mb) |
101
-
102
- > Testing by default with `user` table, with username, email, password fields _so results include password encryption process_ <br>
103
- > To run benchmarks, install *typescript* & *tsx* globally and run `benchmark` `benchmark:bulk` `benchmark:single`
104
-
105
67
  ## Inibase CLI
106
68
 
107
69
  ```shell
@@ -145,48 +107,75 @@ delete <tableName> -w <ID|LineNumber|Criteria>
145
107
  ## Examples
146
108
 
147
109
  <details>
148
- <summary>Schema</summary>
110
+ <summary>Tables</summary>
149
111
  <blockquote>
150
112
 
151
113
  <details>
152
- <summary>Create Schema</summary>
114
+ <summary>Config</summary>
153
115
  <blockquote>
154
116
 
117
+ ```ts
118
+ interface {
119
+ compression: boolean;
120
+ cache: boolean;
121
+ prepend: boolean;
122
+ }
123
+ ```
124
+ </blockquote>
125
+ </details>
126
+
155
127
  <details>
156
- <summary>Using schema.json file</summary>
128
+ <summary>Schema</summary>
157
129
  <blockquote>
158
- Inside the table folder
159
130
 
160
- 1. Create empty folders `.cache` `.tmp`
161
- 2. Create `schema.json` file
162
-
163
- ```jsonc
164
- [
165
- {
166
- // Give a unique ID number for each field
167
- "id": 1,
168
- "key": "username",
169
- "type": "string"
170
- },
171
- {
172
- "id": 2,
173
- "key": "email",
174
- "type": "email"
175
- },
176
- ]
131
+ ```ts
132
+ interface {
133
+ id: number; // stored as a Number but displayed as a hashed ID
134
+ key: string;
135
+ required?: boolean;
136
+ unique?: boolean;
137
+ type: "string" | "number" | "boolean" | "date" | "email" | "url" | "password" | "html" | "ip" | "json" | "id";
138
+ }
139
+ interface Table {
140
+ id: number;
141
+ key: string;
142
+ required?: boolean;
143
+ type: "table";
144
+ table: string;
145
+ }
146
+ interface Array {
147
+ id: number;
148
+ key: string;
149
+ required?: boolean;
150
+ type: "array";
151
+ children: string|string[];
152
+ }
153
+ interface ObjectOrArrayOfObjects {
154
+ id: number;
155
+ key: string;
156
+ required?: boolean;
157
+ type: "object" | "array";
158
+ children: Schema;
159
+ }
177
160
  ```
178
161
  </blockquote>
179
162
  </details>
180
163
 
181
164
  <details>
182
- <summary>Using built-in function</summary>
165
+ <summary>Create Table</summary>
183
166
  <blockquote>
184
167
 
185
168
  ```js
186
169
  import Inibase from "inibase";
187
170
  const db = new Inibase("/databaseName");
188
171
 
189
- const userSchema = [
172
+ const userTableConfig = {
173
+ compression: true,
174
+ cache: true,
175
+ prepend: false
176
+ }
177
+
178
+ const userTableSchema = [
190
179
  {
191
180
  key: "username",
192
181
  type: "string",
@@ -252,14 +241,15 @@ const userSchema = [
252
241
  },
253
242
  ];
254
243
 
255
- await db.setTableSchema("user", userSchema);
244
+ await db.createTable("user", userTableSchema, userTableConfig);
256
245
  ```
257
246
  </blockquote>
258
247
  </details>
259
248
 
260
- </blockquote>
261
- </details>
262
-
249
+ <details>
250
+ <summary>Update Table</summary>
251
+ <blockquote>
252
+
263
253
  <details>
264
254
  <summary>Add field</summary>
265
255
  <blockquote>
@@ -268,10 +258,10 @@ await db.setTableSchema("user", userSchema);
268
258
  import Inibase from "inibase";
269
259
  const db = new Inibase("/databaseName");
270
260
 
271
- const userSchema = await db.getTableSchema("user");
272
- const newUserSchema = [...userSchema, {key: "phone2", type: "number", required: false}];
261
+ const userTableSchema = (await db.getTable("user")).schema;
262
+ const newUserTableSchema = [...userTableSchema, {key: "phone2", type: "number", required: false}];
273
263
 
274
- await db.setTableSchema("user", newUserSchema);
264
+ await db.updateTable("user", newUserTableSchema);
275
265
  ```
276
266
  </blockquote>
277
267
  </details>
@@ -286,13 +276,33 @@ import { setField } from "inibase/utils";
286
276
 
287
277
  const db = new Inibase("/databaseName");
288
278
 
289
- const userSchema = await db.getTableSchema("user");
290
- setField("username", userSchema, {key: "full_name"});
291
- await db.setTableSchema("user", newUserSchema);
279
+ const userTableSchema = (await db.getTable("user")).schema;
280
+ setField("username", userTableSchema, {key: "fullName"});
281
+ await db.updateTable("user", newUserTableSchema);
292
282
  ```
293
283
  </blockquote>
294
284
  </details>
295
285
 
286
+ <details>
287
+ <summary>Remove field</summary>
288
+ <blockquote>
289
+
290
+ ```js
291
+ import Inibase from "inibase";
292
+ import { unsetField } from "inibase/utils";
293
+
294
+ const db = new Inibase("/databaseName");
295
+
296
+ const userTableSchema = (await db.getTable("user")).schema;
297
+ unsetField("fullName", userTableSchema);
298
+ await db.updateTable("user", newUserTableSchema);
299
+ ```
300
+ </blockquote>
301
+ </details>
302
+
303
+ </blockquote>
304
+ </details>
305
+
296
306
  <details>
297
307
  <summary>Join Tables</summary>
298
308
  <blockquote>
@@ -301,7 +311,7 @@ await db.setTableSchema("user", newUserSchema);
301
311
  import Inibase from "inibase";
302
312
  const db = new Inibase("/databaseName");
303
313
 
304
- const productSchema = [
314
+ const productTableSchema = [
305
315
  {
306
316
  key: "title",
307
317
  type: "string",
@@ -319,9 +329,9 @@ const productSchema = [
319
329
  },
320
330
  ];
321
331
 
322
- await db.setTableSchema("product", productSchema);
332
+ await db.createTable("product", productTableSchema);
323
333
 
324
- const productData = [
334
+ const productTableData = [
325
335
  {
326
336
  title: "Product 1",
327
337
  price: 16,
@@ -334,7 +344,7 @@ const productData = [
334
344
  },
335
345
  ];
336
346
 
337
- const product = await db.post("product", productData);
347
+ const product = await db.post("product", productTableData);
338
348
  // [
339
349
  // {
340
350
  // "id": "1d88385d4b1581f8fb059334dec30f4c",
@@ -373,7 +383,7 @@ const product = await db.post("product", productData);
373
383
  import Inibase from "inibase";
374
384
  const db = new Inibase("/databaseName");
375
385
 
376
- const userData = [
386
+ const userTableData = [
377
387
  {
378
388
  username: "user1",
379
389
  email: "user1@example.com",
@@ -408,7 +418,7 @@ const userData = [
408
418
  },
409
419
  ];
410
420
 
411
- const users = await db.post("user", userData);
421
+ const users = await db.post("user", userTableData);
412
422
  // [
413
423
  // {
414
424
  // "id": "1d88385d4b1581f8fb059334dec30f4c",
@@ -664,6 +674,29 @@ await db.sort("user", {age: -1, username: "asc"});
664
674
  </blockquote>
665
675
  </details>
666
676
 
677
+ ## Benchmark
678
+
679
+ ### Bulk
680
+
681
+ | | 10 | 100 | 1000 |
682
+ |--------|-----------------|-----------------|-----------------|
683
+ | POST | 11 ms (0.65 mb) | 19 ms (1.00 mb) | 85 ms (4.58 mb) |
684
+ | GET | 14 ms (2.77 mb) | 12 ms (3.16 mb) | 34 ms (1.38 mb) |
685
+ | PUT | 6 ms (1.11 mb) | 5 ms (1.37 mb) | 10 ms (1.12 mb) |
686
+ | DELETE | 17 ms (1.68 mb) | 14 ms (5.45 mb) | 25 ms (5.94 mb) |
687
+
688
+ ### Single
689
+
690
+ | | 10 | 100 | 1000 |
691
+ |--------|-------------------|--------------------|--------------------|
692
+ | POST | 43 ms (4.70 mb) | 387 ms (6.36 mb) | 5341 ms (24.73 mb) |
693
+ | GET | 99 ms (12.51 mb) | 846 ms (30.68 mb) | 7103 ms (30.86 mb) |
694
+ | PUT | 33 ms (10.29 mb) | 312 ms (11.06 mb) | 3539 ms (14.87 mb) |
695
+ | DELETE | 134 ms (13.50 mb) | 1224 ms (16.57 mb) | 7339 ms (11.46 mb) |
696
+
697
+ > Testing by default with `user` table, with username, email, password fields _so results include password encryption process_ <br>
698
+ > To run benchmarks, install *typescript* & *[tsx](https://github.com/privatenumber/tsx)* globally and run `benchmark` `benchmark:bulk` `benchmark:single`
699
+
667
700
  ## Roadmap
668
701
 
669
702
  - [x] Actions:
@@ -671,7 +704,7 @@ await db.sort("user", {age: -1, username: "asc"});
671
704
  - [x] Pagination
672
705
  - [x] Criteria
673
706
  - [x] Columns
674
- - [x] Sort (using UNIX commands)
707
+ - [x] Sort
675
708
  - [x] POST
676
709
  - [x] PUT
677
710
  - [x] DELETE
package/dist/file.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  import type { ComparisonOperator, FieldType, Schema } from "./index.js";
3
3
  export declare const lock: (folderPath: string, prefix?: string) => Promise<void>;
4
4
  export declare const unlock: (folderPath: string, prefix?: string) => Promise<void>;
5
- export declare const write: (filePath: string, data: any, disableCompression?: boolean) => Promise<void>;
6
- export declare const read: (filePath: string, disableCompression?: boolean) => Promise<string>;
5
+ export declare const write: (filePath: string, data: any) => Promise<void>;
6
+ export declare const read: (filePath: string) => Promise<string>;
7
7
  /**
8
8
  * Checks if a file or directory exists at the specified path.
9
9
  *
@@ -68,7 +68,7 @@ export declare const replace: (filePath: string, replacements: string | number |
68
68
  * @returns Promise<string[]>. Modifies the file by appending data.
69
69
  *
70
70
  */
71
- export declare const append: (filePath: string, data: string | number | (string | number)[]) => Promise<string[]>;
71
+ export declare const append: (filePath: string, data: string | number | (string | number)[], prepend?: boolean) => Promise<string[]>;
72
72
  /**
73
73
  * Asynchronously removes specified lines from a file.
74
74
  *
package/dist/file.js CHANGED
@@ -1,13 +1,12 @@
1
- import { open, access, writeFile, readFile, constants as fsConstants, unlink, copyFile, appendFile, mkdir, } from "node:fs/promises";
1
+ import { open, access, writeFile, readFile, constants as fsConstants, unlink, copyFile, appendFile, } from "node:fs/promises";
2
2
  import { createInterface } from "node:readline";
3
3
  import { Transform } from "node:stream";
4
4
  import { pipeline } from "node:stream/promises";
5
- import { createGzip, createGunzip, gunzipSync, gzipSync } from "node:zlib";
6
- import { dirname, join } from "node:path";
7
- import { detectFieldType, isArrayOfObjects, isJSON, isNumber, isObject, } from "./utils.js";
8
- import { encodeID, compare, exec } from "./utils.server.js";
9
- import * as Config from "./config.js";
5
+ import { createGzip, createGunzip } from "node:zlib";
6
+ import { join } from "node:path";
10
7
  import Inison from "inison";
8
+ import { detectFieldType, isArrayOfObjects, isJSON, isNumber, isObject, } from "./utils.js";
9
+ import { encodeID, compare, exec, gzip, gunzip } from "./utils.server.js";
11
10
  export const lock = async (folderPath, prefix) => {
12
11
  let lockFile = null;
13
12
  const lockFilePath = join(folderPath, `${prefix ?? ""}.locked`);
@@ -29,17 +28,14 @@ export const unlock = async (folderPath, prefix) => {
29
28
  }
30
29
  catch { }
31
30
  };
32
- export const write = async (filePath, data, disableCompression = false) => {
33
- await mkdir(dirname(filePath), { recursive: true });
34
- await writeFile(filePath, Config.isCompressionEnabled && !disableCompression
35
- ? gzipSync(String(data))
36
- : String(data));
31
+ export const write = async (filePath, data) => {
32
+ await writeFile(filePath, filePath.endsWith(".gz") ? await gzip(data) : data);
37
33
  };
38
- export const read = async (filePath, disableCompression = false) => Config.isCompressionEnabled && !disableCompression
39
- ? gunzipSync(await readFile(filePath)).toString()
40
- : (await readFile(filePath)).toString();
41
- const _pipeline = async (rl, writeStream, transform) => {
42
- if (Config.isCompressionEnabled)
34
+ export const read = async (filePath) => filePath.endsWith(".gz")
35
+ ? (await gunzip(await readFile(filePath, "utf8"))).toString()
36
+ : await readFile(filePath, "utf8");
37
+ const _pipeline = async (filePath, rl, writeStream, transform) => {
38
+ if (filePath.endsWith(".gz"))
43
39
  await pipeline(rl, transform, createGzip(), writeStream);
44
40
  else
45
41
  await pipeline(rl, transform, writeStream);
@@ -50,8 +46,8 @@ const _pipeline = async (rl, writeStream, transform) => {
50
46
  * @param fileHandle - The file handle from which to create a read stream.
51
47
  * @returns A readline.Interface instance configured with the provided file stream.
52
48
  */
53
- const readLineInternface = (fileHandle) => createInterface({
54
- input: Config.isCompressionEnabled
49
+ const createReadLineInternface = (filePath, fileHandle) => createInterface({
50
+ input: filePath.endsWith(".gz")
55
51
  ? fileHandle.createReadStream().pipe(createGunzip())
56
52
  : fileHandle.createReadStream(),
57
53
  crlfDelay: Number.POSITIVE_INFINITY,
@@ -185,7 +181,7 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
185
181
  let rl = null;
186
182
  try {
187
183
  fileHandle = await open(filePath, "r");
188
- rl = readLineInternface(fileHandle);
184
+ rl = createReadLineInternface(filePath, fileHandle);
189
185
  const lines = {};
190
186
  let linesCount = 0;
191
187
  if (!lineNumbers) {
@@ -194,17 +190,17 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
194
190
  lines[linesCount] = decode(line, fieldType, fieldChildrenType, secretKey);
195
191
  }
196
192
  }
197
- else if (lineNumbers === -1) {
198
- let lastLine = null;
199
- for await (const line of rl) {
200
- linesCount++;
201
- lastLine = line;
202
- }
203
- if (lastLine)
204
- lines[linesCount] = decode(lastLine, fieldType, fieldChildrenType, secretKey);
193
+ else if (lineNumbers == -1) {
194
+ const command = filePath.endsWith(".gz")
195
+ ? `zcat ${filePath} | sed -n '$p'`
196
+ : `sed -n '$p' ${filePath}`, foundedLine = (await exec(command)).stdout.trim();
197
+ if (foundedLine)
198
+ lines[linesCount] = decode(foundedLine, fieldType, fieldChildrenType, secretKey);
205
199
  }
206
200
  else {
207
201
  lineNumbers = Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers];
202
+ if (lineNumbers.some(Number.isNaN))
203
+ throw new Error("UNVALID_LINE_NUMBERS");
208
204
  if (readWholeFile) {
209
205
  const lineNumbersArray = new Set(lineNumbers);
210
206
  for await (const line of rl) {
@@ -216,9 +212,9 @@ export async function get(filePath, lineNumbers, fieldType, fieldChildrenType, s
216
212
  }
217
213
  return [lines, linesCount];
218
214
  }
219
- const command = Config.isCompressionEnabled
215
+ const command = filePath.endsWith(".gz")
220
216
  ? `zcat ${filePath} | sed -n '${lineNumbers.join("p;")}p'`
221
- : `sed -n '${lineNumbers.join("p;")}p' ${filePath}`, foundedLines = (await exec(command)).stdout.trim().split(/\r?\n/);
217
+ : `sed -n '${lineNumbers.join("p;")}p' ${filePath}`, foundedLines = (await exec(command)).stdout.trim().split("\n");
222
218
  let index = 0;
223
219
  for (const line of foundedLines) {
224
220
  lines[lineNumbers[index]] = decode(line, fieldType, fieldChildrenType, secretKey);
@@ -253,8 +249,8 @@ export const replace = async (filePath, replacements) => {
253
249
  let linesCount = 0;
254
250
  fileHandle = await open(filePath, "r");
255
251
  fileTempHandle = await open(fileTempPath, "w");
256
- rl = readLineInternface(fileHandle);
257
- await _pipeline(rl, fileTempHandle.createWriteStream(), new Transform({
252
+ rl = createReadLineInternface(filePath, fileHandle);
253
+ await _pipeline(filePath, rl, fileTempHandle.createWriteStream(), new Transform({
258
254
  transform(line, encoding, callback) {
259
255
  linesCount++;
260
256
  const replacement = isObject(replacements)
@@ -297,10 +293,10 @@ export const replace = async (filePath, replacements) => {
297
293
  * @returns Promise<string[]>. Modifies the file by appending data.
298
294
  *
299
295
  */
300
- export const append = async (filePath, data) => {
296
+ export const append = async (filePath, data, prepend) => {
301
297
  const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
302
298
  if (await isExists(filePath)) {
303
- if (!Config.isReverseEnabled && !Config.isCompressionEnabled) {
299
+ if (!prepend && !filePath.endsWith(".gz")) {
304
300
  await copyFile(filePath, fileTempPath);
305
301
  await appendFile(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
306
302
  }
@@ -311,9 +307,9 @@ export const append = async (filePath, data) => {
311
307
  try {
312
308
  fileHandle = await open(filePath, "r");
313
309
  fileTempHandle = await open(fileTempPath, "w");
314
- rl = readLineInternface(fileHandle);
310
+ rl = createReadLineInternface(filePath, fileHandle);
315
311
  let isAppended = false;
316
- await _pipeline(rl, fileTempHandle.createWriteStream(), new Transform({
312
+ await _pipeline(filePath, rl, fileTempHandle.createWriteStream(), new Transform({
317
313
  transform(line, _, callback) {
318
314
  if (!isAppended) {
319
315
  isAppended = true;
@@ -332,7 +328,7 @@ export const append = async (filePath, data) => {
332
328
  }
333
329
  }
334
330
  else
335
- await write(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`, undefined);
331
+ await write(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
336
332
  return [fileTempPath, filePath];
337
333
  };
338
334
  /**
@@ -348,9 +344,11 @@ export const remove = async (filePath, linesToDelete) => {
348
344
  linesToDelete = Array.isArray(linesToDelete)
349
345
  ? linesToDelete.map(Number)
350
346
  : [Number(linesToDelete)];
347
+ if (linesToDelete.some(Number.isNaN))
348
+ throw new Error("UNVALID_LINE_NUMBERS");
351
349
  const fileTempPath = filePath.replace(/([^/]+)\/?$/, ".tmp/$1");
352
350
  if (linesToDelete.length < 1000) {
353
- const command = Config.isCompressionEnabled
351
+ const command = filePath.endsWith(".gz")
354
352
  ? `zcat ${filePath} | sed "${linesToDelete.join("d;")}d" | gzip > ${fileTempPath}`
355
353
  : `sed "${linesToDelete.join("d;")}d" ${filePath} > ${fileTempPath}`;
356
354
  await exec(command);
@@ -361,8 +359,8 @@ export const remove = async (filePath, linesToDelete) => {
361
359
  const fileHandle = await open(filePath, "r");
362
360
  const fileTempHandle = await open(fileTempPath, "w");
363
361
  const linesToDeleteArray = new Set(linesToDelete);
364
- const rl = readLineInternface(fileHandle);
365
- await _pipeline(rl, fileTempHandle.createWriteStream(), new Transform({
362
+ const rl = createReadLineInternface(filePath, fileHandle);
363
+ await _pipeline(filePath, rl, fileTempHandle.createWriteStream(), new Transform({
366
364
  transform(line, _, callback) {
367
365
  linesCount++;
368
366
  if (linesToDeleteArray.has(linesCount)) {
@@ -414,7 +412,7 @@ export const search = async (filePath, operator, comparedAtValue, logicalOperato
414
412
  // Open the file for reading.
415
413
  fileHandle = await open(filePath, "r");
416
414
  // Create a Readline interface to read the file line by line.
417
- rl = readLineInternface(fileHandle);
415
+ rl = createReadLineInternface(filePath, fileHandle);
418
416
  // Iterate through each line in the file.
419
417
  for await (const line of rl) {
420
418
  // Increment the line count for each line.
@@ -474,7 +472,7 @@ export const count = async (filePath) => {
474
472
  let rl = null;
475
473
  try {
476
474
  fileHandle = await open(filePath, "r");
477
- rl = readLineInternface(fileHandle);
475
+ rl = createReadLineInternface(filePath, fileHandle);
478
476
  for await (const _ of rl)
479
477
  linesCount++;
480
478
  }
@@ -497,7 +495,7 @@ export const count = async (filePath) => {
497
495
  export const sum = async (filePath, lineNumbers) => {
498
496
  let sum = 0;
499
497
  const fileHandle = await open(filePath, "r");
500
- const rl = readLineInternface(fileHandle);
498
+ const rl = createReadLineInternface(filePath, fileHandle);
501
499
  if (lineNumbers) {
502
500
  let linesCount = 0;
503
501
  const lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
@@ -529,7 +527,7 @@ export const sum = async (filePath, lineNumbers) => {
529
527
  export const max = async (filePath, lineNumbers) => {
530
528
  let max = 0;
531
529
  const fileHandle = await open(filePath, "r");
532
- const rl = readLineInternface(fileHandle);
530
+ const rl = createReadLineInternface(filePath, fileHandle);
533
531
  if (lineNumbers) {
534
532
  let linesCount = 0;
535
533
  const lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
@@ -566,7 +564,7 @@ export const max = async (filePath, lineNumbers) => {
566
564
  export const min = async (filePath, lineNumbers) => {
567
565
  let min = 0;
568
566
  const fileHandle = await open(filePath, "r");
569
- const rl = readLineInternface(fileHandle);
567
+ const rl = createReadLineInternface(filePath, fileHandle);
570
568
  if (lineNumbers) {
571
569
  let linesCount = 0;
572
570
  const lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
package/dist/index.d.ts CHANGED
@@ -23,6 +23,15 @@ export interface Options {
23
23
  columns?: string[] | string;
24
24
  order?: Record<string, "asc" | "desc">;
25
25
  }
26
+ export interface Config {
27
+ compression: boolean;
28
+ cache: boolean;
29
+ prepend: boolean;
30
+ }
31
+ export interface TableObject {
32
+ schema?: Schema;
33
+ config: Config;
34
+ }
26
35
  export type ComparisonOperator = "=" | "!=" | ">" | "<" | ">=" | "<=" | "*" | "!*" | "[]" | "![]";
27
36
  type pageInfo = {
28
37
  total?: number;
@@ -41,24 +50,25 @@ declare global {
41
50
  entries<T extends object>(o: T): Entries<T>;
42
51
  }
43
52
  }
44
- export type ErrorCodes = "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "NO_ITEMS" | "NO_RESULTS" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS" | "NO_ENV";
53
+ export type ErrorCodes = "FIELD_UNIQUE" | "FIELD_REQUIRED" | "NO_SCHEMA" | "NO_ITEMS" | "NO_RESULTS" | "INVALID_ID" | "INVALID_TYPE" | "INVALID_PARAMETERS" | "NO_ENV" | "TABLE_EXISTS" | "TABLE_NOT_EXISTS";
45
54
  export type ErrorLang = "en";
46
55
  export default class Inibase {
47
- folder: string;
48
- database: string;
49
- table: string | null;
50
56
  pageInfo: Record<string, pageInfo>;
57
+ salt: Buffer;
58
+ private databasePath;
59
+ private tables;
51
60
  private fileExtension;
52
61
  private checkIFunique;
53
62
  private totalItems;
54
- salt: Buffer;
55
- constructor(database: string, mainFolder?: string, _table?: string | null, _totalItems?: Record<string, number>, _pageInfo?: Record<string, pageInfo>, _isThreadEnabled?: boolean);
63
+ constructor(database: string, mainFolder?: string);
56
64
  private throwError;
57
65
  private getFileExtension;
58
66
  private _schemaToIdsPath;
59
- setTableSchema(tableName: string, schema: Schema): Promise<void>;
67
+ createTable(tableName: string, schema?: Schema, config?: Config): Promise<void>;
68
+ updateTable(tableName: string, schema?: Schema, config?: Config): Promise<void>;
69
+ getTable(tableName: string): Promise<TableObject>;
60
70
  getTableSchema(tableName: string, encodeIDs?: boolean): Promise<Schema | undefined>;
61
- private getSchemaWhenTableNotEmpty;
71
+ private throwErrorIfTableEmpty;
62
72
  private validateData;
63
73
  private formatField;
64
74
  private checkUnique;
@@ -66,15 +76,14 @@ export default class Inibase {
66
76
  private getDefaultValue;
67
77
  private _combineObjectsToArray;
68
78
  private _CombineData;
69
- private _addPathToKeys;
70
79
  private joinPathesContents;
71
80
  private _getItemsFromSchemaHelper;
72
81
  private getItemsFromSchema;
73
82
  private applyCriteria;
74
83
  private _filterSchemaByColumns;
75
84
  clearCache(tablePath: string): Promise<void>;
76
- get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: true, onlyLinesNumbers?: undefined, tableSchema?: Schema, skipIdColumn?: boolean): Promise<Data | null>;
77
- get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: boolean | undefined, onlyLinesNumbers?: true, tableSchema?: Schema, skipIdColumn?: boolean): Promise<number[]>;
85
+ get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: true, onlyLinesNumbers?: undefined, _skipIdColumn?: boolean): Promise<Data | null>;
86
+ get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: boolean | undefined, onlyLinesNumbers?: true, _skipIdColumn?: boolean): Promise<number[]>;
78
87
  post(tableName: string, data: Data | Data[], options?: Options, returnPostedData?: boolean): Promise<void>;
79
88
  post(tableName: string, data: Data, options: Options | undefined, returnPostedData: true): Promise<Data | null>;
80
89
  post(tableName: string, data: Data[], options: Options | undefined, returnPostedData: true): Promise<Data[] | null>;