@kidus.dev/flowdb 1.0.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 (74) hide show
  1. package/README.md +15 -0
  2. package/dist/core/blob/blob.d.ts +25 -0
  3. package/dist/core/blob/blob.d.ts.map +1 -0
  4. package/dist/core/blob/blob.js +57 -0
  5. package/dist/core/blob/blob_disk_driver.d.ts +27 -0
  6. package/dist/core/blob/blob_disk_driver.d.ts.map +1 -0
  7. package/dist/core/blob/blob_disk_driver.js +179 -0
  8. package/dist/core/blob/blob_storage.d.ts +90 -0
  9. package/dist/core/blob/blob_storage.d.ts.map +1 -0
  10. package/dist/core/blob/blob_storage.js +248 -0
  11. package/dist/core/collection/collection.d.ts +99 -0
  12. package/dist/core/collection/collection.d.ts.map +1 -0
  13. package/dist/core/collection/collection.js +226 -0
  14. package/dist/core/collection/document.d.ts +24 -0
  15. package/dist/core/collection/document.d.ts.map +1 -0
  16. package/dist/core/collection/document.js +86 -0
  17. package/dist/core/collection/driver/collection_file_driver.d.ts +20 -0
  18. package/dist/core/collection/driver/collection_file_driver.d.ts.map +1 -0
  19. package/dist/core/collection/driver/collection_file_driver.js +90 -0
  20. package/dist/core/collection/driver/collection_operations.d.ts +43 -0
  21. package/dist/core/collection/driver/collection_operations.d.ts.map +1 -0
  22. package/dist/core/collection/driver/collection_operations.js +278 -0
  23. package/dist/core/collection/query/compares.d.ts +90 -0
  24. package/dist/core/collection/query/compares.d.ts.map +1 -0
  25. package/dist/core/collection/query/compares.js +362 -0
  26. package/dist/core/collection/query/filtering.d.ts +14 -0
  27. package/dist/core/collection/query/filtering.d.ts.map +1 -0
  28. package/dist/core/collection/query/filtering.js +176 -0
  29. package/dist/core/collection/query/query_builder.d.ts +145 -0
  30. package/dist/core/collection/query/query_builder.d.ts.map +1 -0
  31. package/dist/core/collection/query/query_builder.js +196 -0
  32. package/dist/core/collection/query/query_executor.d.ts +87 -0
  33. package/dist/core/collection/query/query_executor.d.ts.map +1 -0
  34. package/dist/core/collection/query/query_executor.js +348 -0
  35. package/dist/core/collection/query/relation.d.ts +29 -0
  36. package/dist/core/collection/query/relation.d.ts.map +1 -0
  37. package/dist/core/collection/query/relation.js +40 -0
  38. package/dist/core/database/backup.d.ts +26 -0
  39. package/dist/core/database/backup.d.ts.map +1 -0
  40. package/dist/core/database/backup.js +114 -0
  41. package/dist/core/database/database.d.ts +57 -0
  42. package/dist/core/database/database.d.ts.map +1 -0
  43. package/dist/core/database/database.js +179 -0
  44. package/dist/core/database/database_file_driver.d.ts +27 -0
  45. package/dist/core/database/database_file_driver.d.ts.map +1 -0
  46. package/dist/core/database/database_file_driver.js +135 -0
  47. package/dist/core/store/store.d.ts +24 -0
  48. package/dist/core/store/store.d.ts.map +1 -0
  49. package/dist/core/store/store.js +54 -0
  50. package/dist/core/store/store_file_driver.d.ts +26 -0
  51. package/dist/core/store/store_file_driver.d.ts.map +1 -0
  52. package/dist/core/store/store_file_driver.js +87 -0
  53. package/dist/tools/encryptor.d.ts +17 -0
  54. package/dist/tools/encryptor.d.ts.map +1 -0
  55. package/dist/tools/encryptor.js +80 -0
  56. package/dist/tools/format.d.ts +10 -0
  57. package/dist/tools/format.d.ts.map +1 -0
  58. package/dist/tools/format.js +40 -0
  59. package/dist/tools/index.d.ts +7 -0
  60. package/dist/tools/index.d.ts.map +1 -0
  61. package/dist/tools/index.js +6 -0
  62. package/dist/tools/json.d.ts +19 -0
  63. package/dist/tools/json.d.ts.map +1 -0
  64. package/dist/tools/json.js +232 -0
  65. package/dist/tools/performance.d.ts +20 -0
  66. package/dist/tools/performance.d.ts.map +1 -0
  67. package/dist/tools/performance.js +53 -0
  68. package/dist/tools/print_colored.d.ts +47 -0
  69. package/dist/tools/print_colored.d.ts.map +1 -0
  70. package/dist/tools/print_colored.js +119 -0
  71. package/dist/tools/random.d.ts +46 -0
  72. package/dist/tools/random.d.ts.map +1 -0
  73. package/dist/tools/random.js +214 -0
  74. package/package.json +40 -0
@@ -0,0 +1,40 @@
1
+ import Collection from "../collection";
2
+ export default class Relation {
3
+ name;
4
+ localCollection;
5
+ localKey;
6
+ foreignCollection;
7
+ foreignKey;
8
+ type;
9
+ constructor(params) {
10
+ this.name = params.name;
11
+ this.localCollection = params.localCollection;
12
+ this.localKey = params.localKey;
13
+ this.foreignCollection = params.foreignCollection;
14
+ this.foreignKey = params.foreignKey;
15
+ this.type = params.type;
16
+ }
17
+ toJson() {
18
+ return {
19
+ name: this.name,
20
+ localCollection: this.localCollection,
21
+ localKey: this.localKey,
22
+ foreignCollection: this.foreignCollection,
23
+ foreignKey: this.foreignKey,
24
+ type: this.type,
25
+ };
26
+ }
27
+ static fromJson(json) {
28
+ return new Relation({
29
+ name: json.name,
30
+ localCollection: json.localCollection,
31
+ localKey: json.localKey,
32
+ foreignCollection: json.foreignCollection,
33
+ foreignKey: json.foreignKey,
34
+ type: json.type,
35
+ });
36
+ }
37
+ toString() {
38
+ return `Relation(name: ${this.name}, localCollection: ${this.localCollection}, localKey: ${this.localKey}, foreignCollection: ${this.foreignCollection}, foreignKey: ${this.foreignKey}, type: ${this.type})`;
39
+ }
40
+ }
@@ -0,0 +1,26 @@
1
+ export default class Backup {
2
+ name: string;
3
+ databaseDirectory: string;
4
+ backupDirectory: string;
5
+ metaFile: string;
6
+ meta: {
7
+ [key: string]: any;
8
+ };
9
+ static getBackupsDirectory(databaseDirectory: string): string;
10
+ constructor({ databaseDirectory, name, }: {
11
+ databaseDirectory: string;
12
+ name: string;
13
+ });
14
+ get size(): number;
15
+ get sizeFormatted(): string;
16
+ create(): void;
17
+ static fromPath(p_: string): Backup;
18
+ static fromName(name: string, databaseDirectory: string): Backup;
19
+ static create({ databaseDirectory, name, }: {
20
+ databaseDirectory: string;
21
+ name: string;
22
+ }): Backup;
23
+ delete(): void;
24
+ toString(): string;
25
+ }
26
+ //# sourceMappingURL=backup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../../src/core/database/backup.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IAE7B,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM;gBAIjD,EACV,iBAAiB,EACjB,IAAI,GACL,EAAE;QACD,iBAAiB,EAAE,MAAM,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;KACd;IAeD,IAAI,IAAI,IAAI,MAAM,CAajB;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,MAAM,IAAI,IAAI;IASd,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAOnC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM;IAIhE,MAAM,CAAC,MAAM,CAAC,EACZ,iBAAiB,EACjB,IAAI,GACL,EAAE;QACD,iBAAiB,EAAE,MAAM,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,MAAM;IAsCV,MAAM,IAAI,IAAI;IAmBd,QAAQ,IAAI,MAAM;CAGnB"}
@@ -0,0 +1,114 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import Format from "../../tools/format";
4
+ export default class Backup {
5
+ name;
6
+ databaseDirectory;
7
+ backupDirectory;
8
+ metaFile;
9
+ meta;
10
+ static getBackupsDirectory(databaseDirectory) {
11
+ return path.join(databaseDirectory, "backups");
12
+ }
13
+ constructor({ databaseDirectory, name, }) {
14
+ this.name = name;
15
+ this.databaseDirectory = databaseDirectory;
16
+ this.backupDirectory = path.join(Backup.getBackupsDirectory(databaseDirectory), name);
17
+ this.metaFile = path.join(this.backupDirectory, "meta.json");
18
+ this.meta = {
19
+ database: this.databaseDirectory,
20
+ backup: this.backupDirectory,
21
+ timestamp: new Date().toISOString(),
22
+ };
23
+ }
24
+ get size() {
25
+ if (!fs.existsSync(this.backupDirectory))
26
+ return 0;
27
+ const getSize = (dir) => fs.readdirSync(dir, { withFileTypes: true }).reduce((acc, entry) => {
28
+ const p = path.join(dir, entry.name);
29
+ if (entry.isFile()) {
30
+ return acc + fs.statSync(p).size;
31
+ }
32
+ else if (entry.isDirectory()) {
33
+ return acc + getSize(p);
34
+ }
35
+ return acc;
36
+ }, 0);
37
+ return getSize(this.backupDirectory);
38
+ }
39
+ get sizeFormatted() {
40
+ return Format.sizeToHumanReadable(this.size);
41
+ }
42
+ create() {
43
+ if (!fs.existsSync(this.backupDirectory))
44
+ fs.mkdirSync(this.backupDirectory, { recursive: true });
45
+ if (!fs.existsSync(this.metaFile)) {
46
+ fs.writeFileSync(this.metaFile, JSON.stringify(this.meta, null, 2));
47
+ }
48
+ this.meta = JSON.parse(fs.readFileSync(this.metaFile, "utf-8"));
49
+ }
50
+ static fromPath(p_) {
51
+ return new Backup({
52
+ name: path.basename(p_),
53
+ databaseDirectory: path.dirname(p_),
54
+ });
55
+ }
56
+ static fromName(name, databaseDirectory) {
57
+ return new Backup({ name, databaseDirectory });
58
+ }
59
+ static create({ databaseDirectory, name, }) {
60
+ const backup = Backup.fromName(name, databaseDirectory);
61
+ backup.create();
62
+ const walk = (dir) => {
63
+ let results = [];
64
+ for (const entry of fs.readdirSync(dir)) {
65
+ const p_ = path.join(dir, entry);
66
+ const stat = fs.statSync(p_);
67
+ if (p_.includes("backup") ||
68
+ (stat.isDirectory() && path.basename(p_) === "backups")) {
69
+ continue;
70
+ }
71
+ if (stat.isFile()) {
72
+ results.push(p_);
73
+ }
74
+ else if (stat.isDirectory()) {
75
+ results = results.concat(walk(p_));
76
+ }
77
+ }
78
+ return results;
79
+ };
80
+ const list = walk(databaseDirectory);
81
+ for (const file of list) {
82
+ const relativePath = path.relative(databaseDirectory, file);
83
+ const newPath = path.join(backup.backupDirectory, relativePath);
84
+ const dirName = path.dirname(newPath);
85
+ if (!fs.existsSync(dirName)) {
86
+ fs.mkdirSync(dirName, { recursive: true });
87
+ }
88
+ fs.copyFileSync(file, newPath);
89
+ }
90
+ return backup;
91
+ }
92
+ delete() {
93
+ if (fs.existsSync(this.backupDirectory)) {
94
+ const rmDir = (dirPath) => {
95
+ if (fs.existsSync(dirPath)) {
96
+ for (const entry of fs.readdirSync(dirPath)) {
97
+ const curPath = path.join(dirPath, entry);
98
+ if (fs.lstatSync(curPath).isDirectory()) {
99
+ rmDir(curPath);
100
+ }
101
+ else {
102
+ fs.unlinkSync(curPath);
103
+ }
104
+ }
105
+ fs.rmdirSync(dirPath);
106
+ }
107
+ };
108
+ rmDir(this.backupDirectory);
109
+ }
110
+ }
111
+ toString() {
112
+ return `Backup [ ${this.databaseDirectory} • ${this.name} • ${this.sizeFormatted} • ${this.meta["timestamp"]} ]`;
113
+ }
114
+ }
@@ -0,0 +1,57 @@
1
+ import Collection from "../collection/collection";
2
+ import Store from "../store/store";
3
+ import BlobStorage from "../blob/blob_storage";
4
+ import Backup from "./backup";
5
+ export interface DatabaseOptions {
6
+ path?: string;
7
+ encrypted?: boolean;
8
+ secretKey?: string;
9
+ }
10
+ export declare function openDatabase(name: string, options?: DatabaseOptions): Database;
11
+ export default class Database {
12
+ readonly name: string;
13
+ private readonly _storage;
14
+ private readonly _encrypted;
15
+ private readonly _collections;
16
+ private readonly _stores;
17
+ private readonly _blobStorages;
18
+ constructor(name: string, { path, encrypted, secretKey }?: DatabaseOptions);
19
+ static open(name: string, options?: DatabaseOptions): Database;
20
+ get path(): string;
21
+ get encrypted(): boolean;
22
+ get size(): number;
23
+ get sizeFormatted(): string;
24
+ get collections(): Map<string, Collection>;
25
+ get stores(): Map<string, Store>;
26
+ get blobStorages(): Map<string, BlobStorage>;
27
+ collectionsList(options?: {
28
+ pick?: string[];
29
+ omit?: string[];
30
+ }): Collection[];
31
+ storesList(options?: {
32
+ pick?: string[];
33
+ omit?: string[];
34
+ }): Store[];
35
+ storeExists(name: string): boolean;
36
+ store(name: string): Store;
37
+ collectionExists(name: string): boolean;
38
+ collection(name: string): Collection;
39
+ blobStorageExists(name: string): boolean;
40
+ blobStorage(name: string, options?: {
41
+ chunksSize?: number;
42
+ encrypt?: boolean;
43
+ secretKey?: string;
44
+ }): BlobStorage;
45
+ get backups(): Backup[];
46
+ backup(name: string): Backup;
47
+ removeBackup(name: string): void;
48
+ removeAllBackups(): void;
49
+ reset(): void;
50
+ clear(): void;
51
+ drop(): void;
52
+ dropStore(storeName: string): void;
53
+ dropCollection(collectionName: string): void;
54
+ dropBlobStorage(blobStorageName: string): void;
55
+ toString(): string;
56
+ }
57
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/core/database/database.ts"],"names":[],"mappings":"AAIA,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAClD,OAAO,KAAK,MAAM,gBAAgB,CAAC;AACnC,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAC/C,OAAO,MAAM,MAAM,UAAU,CAAC;AAG9B,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,eAAoB,GAC5B,QAAQ,CAEV;AAED,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IAErC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuC;gBAGnE,IAAI,EAAE,MAAM,EACZ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,GAAE,eAAoB;IAmBtD,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,QAAQ;IAIlE,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAEzC;IACD,IAAI,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAE/B;IACD,IAAI,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAE3C;IAED,eAAe,CAAC,OAAO,CAAC,EAAE;QACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG,UAAU,EAAE;IAoBhB,UAAU,CAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,KAAK,EAAE;IAqBnE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAGlC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAc1B,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAGvC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAcpC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAGxC,WAAW,CACT,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QACP,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACf,GACL,WAAW;IAmBd,IAAI,OAAO,IAAI,MAAM,EAAE,CAEtB;IACD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK5B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAGhC,gBAAgB,IAAI,IAAI;IAKxB,KAAK,IAAI,IAAI;IAGb,KAAK,IAAI,IAAI;IAGb,IAAI,IAAI,IAAI;IAGZ,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAGlC,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAG5C,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI;IAI9C,QAAQ,IAAI,MAAM;CAGnB"}
@@ -0,0 +1,179 @@
1
+ // The following is a TypeScript port of the Database API from the Dart code.
2
+ import { Format } from "../../tools";
3
+ import { DatabaseFileDriver } from "./database_file_driver";
4
+ import Collection from "../collection/collection";
5
+ import Store from "../store/store";
6
+ import BlobStorage from "../blob/blob_storage";
7
+ import Backup from "./backup";
8
+ // database factory function for convenience
9
+ export function openDatabase(name, options = {}) {
10
+ return Database.open(name, options);
11
+ }
12
+ export default class Database {
13
+ name;
14
+ _storage;
15
+ _encrypted;
16
+ _collections = new Map();
17
+ _stores = new Map();
18
+ _blobStorages = new Map();
19
+ constructor(name, { path, encrypted, secretKey } = {}) {
20
+ this.name = name;
21
+ this._storage = new DatabaseFileDriver({
22
+ name,
23
+ dbPath: path ?? name,
24
+ encrypted: encrypted ?? false,
25
+ });
26
+ this._encrypted = encrypted ?? false;
27
+ // Add existing collections and stores
28
+ Object.entries(this._storage.getCollections() ?? {}).forEach(([k, v]) => this._collections.set(k, v));
29
+ Object.entries(this._storage.getStores?.() ?? {}).forEach(([k, v]) => this._stores.set(k, v));
30
+ }
31
+ static open(name, options = {}) {
32
+ return new Database(name, options);
33
+ }
34
+ get path() {
35
+ return this._storage.dbPath;
36
+ }
37
+ get encrypted() {
38
+ return this._encrypted;
39
+ }
40
+ get size() {
41
+ return this._storage.size;
42
+ }
43
+ get sizeFormatted() {
44
+ return Format.sizeToHumanReadable(this.size);
45
+ }
46
+ get collections() {
47
+ return this._collections;
48
+ }
49
+ get stores() {
50
+ return this._stores;
51
+ }
52
+ get blobStorages() {
53
+ return this._blobStorages;
54
+ }
55
+ collectionsList(options) {
56
+ const { pick, omit } = options || {};
57
+ if (pick && omit) {
58
+ throw new Error("pick and omit cannot be used together");
59
+ }
60
+ if (pick) {
61
+ return Array.from(this._collections.keys())
62
+ .filter((e) => pick.includes(e))
63
+ .map((e) => this._collections.get(e))
64
+ .filter(Boolean);
65
+ }
66
+ if (omit) {
67
+ return Array.from(this._collections.keys())
68
+ .filter((e) => !omit.includes(e))
69
+ .map((e) => this._collections.get(e))
70
+ .filter(Boolean);
71
+ }
72
+ return Array.from(this._collections.values());
73
+ }
74
+ storesList(options) {
75
+ const { pick, omit } = options || {};
76
+ if (pick && omit) {
77
+ throw new Error("pick and omit cannot be used together");
78
+ }
79
+ if (pick) {
80
+ return Array.from(this._stores.keys())
81
+ .filter((e) => pick.includes(e))
82
+ .map((e) => this._stores.get(e))
83
+ .filter(Boolean);
84
+ }
85
+ if (omit) {
86
+ return Array.from(this._stores.keys())
87
+ .filter((e) => !omit.includes(e))
88
+ .map((e) => this._stores.get(e))
89
+ .filter(Boolean);
90
+ }
91
+ return Array.from(this._stores.values());
92
+ }
93
+ // STORES;
94
+ storeExists(name) {
95
+ return this._stores.has(name);
96
+ }
97
+ store(name) {
98
+ if (!this._stores.has(name)) {
99
+ const s = new Store({
100
+ name,
101
+ path: `${this.path}/stores/${name}`,
102
+ encrypted: this._encrypted,
103
+ });
104
+ s.create?.();
105
+ this._stores.set(name, s);
106
+ }
107
+ return this._stores.get(name);
108
+ }
109
+ // COLLECTIONS
110
+ collectionExists(name) {
111
+ return this._collections.has(name);
112
+ }
113
+ collection(name) {
114
+ if (!this._collections.has(name)) {
115
+ const c = new Collection({
116
+ name,
117
+ path: `${this.path}/collections/${name}`,
118
+ encrypted: this._encrypted,
119
+ database: this,
120
+ });
121
+ this._collections.set(name, c);
122
+ }
123
+ return this._collections.get(name);
124
+ }
125
+ // BLOBS
126
+ blobStorageExists(name) {
127
+ return this._blobStorages.has(name);
128
+ }
129
+ blobStorage(name, options = {}) {
130
+ const { chunksSize = 1024 * 512 /* 524288 */, encrypt, secretKey, } = options;
131
+ if (!this._blobStorages.has(name)) {
132
+ const bs = new BlobStorage({
133
+ name,
134
+ path: `${this.path}/blobs/${name}`,
135
+ chunksSize,
136
+ encrypted: this._encrypted,
137
+ });
138
+ this._blobStorages.set(name, bs);
139
+ }
140
+ return this._blobStorages.get(name);
141
+ }
142
+ // BACKUPS
143
+ get backups() {
144
+ return this._storage.getBackups();
145
+ }
146
+ backup(name) {
147
+ const backup = this._storage.backup(name);
148
+ backup.create();
149
+ return backup;
150
+ }
151
+ removeBackup(name) {
152
+ this._storage.removeBackup(name);
153
+ }
154
+ removeAllBackups() {
155
+ this._storage.removeAllBackups();
156
+ }
157
+ // RESET/CLEAR/DROP
158
+ reset() {
159
+ this._storage.reset();
160
+ }
161
+ clear() {
162
+ this.reset();
163
+ }
164
+ drop() {
165
+ this._storage.delete();
166
+ }
167
+ dropStore(storeName) {
168
+ this.store(storeName).drop();
169
+ }
170
+ dropCollection(collectionName) {
171
+ this.collection(collectionName).drop();
172
+ }
173
+ dropBlobStorage(blobStorageName) {
174
+ this.blobStorage(blobStorageName).clear();
175
+ }
176
+ toString() {
177
+ return `Database [ ${this.name} • ${this.sizeFormatted} • ${this.collections.size} collections ]`;
178
+ }
179
+ }
@@ -0,0 +1,27 @@
1
+ import Collection from "../collection/collection";
2
+ import Store from "../store/store";
3
+ import Backup from "./backup";
4
+ export declare class DatabaseFileDriver {
5
+ name: string;
6
+ dbPath: string;
7
+ directory: string;
8
+ encrypted: boolean;
9
+ constructor({ name, dbPath, encrypted, }: {
10
+ name: string;
11
+ dbPath: string;
12
+ encrypted: boolean;
13
+ });
14
+ get size(): number;
15
+ create(): void;
16
+ delete(): void;
17
+ reset(): void;
18
+ backup(backupName: string): Backup;
19
+ removeBackup(backupName: string): void;
20
+ removeAllBackups(): void;
21
+ getBackups(): Backup[];
22
+ getCollections(): Collection[];
23
+ getStores(): Record<string, Store>;
24
+ private _getDirectorySize;
25
+ private _copyRecursive;
26
+ }
27
+ //# sourceMappingURL=database_file_driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database_file_driver.d.ts","sourceRoot":"","sources":["../../../src/core/database/database_file_driver.ts"],"names":[],"mappings":"AAGA,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAClD,OAAO,KAAK,MAAM,gBAAgB,CAAC;AACnC,OAAO,MAAM,MAAM,UAAU,CAAC;AAE9B,qBAAa,kBAAkB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;gBAEP,EACV,IAAI,EACJ,MAAM,EACN,SAAS,GACV,EAAE;QACD,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,OAAO,CAAC;KACpB;IAOD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,IAAI;IAKd,MAAM,IAAI,IAAI;IAKd,KAAK,IAAI,IAAI;IAKb,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAWlC,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAOtC,gBAAgB,IAAI,IAAI;IAOxB,UAAU,IAAI,MAAM,EAAE;IAetB,cAAc,IAAI,UAAU,EAAE;IAiB9B,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAuBlC,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,cAAc;CAmBvB"}
@@ -0,0 +1,135 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import Collection from "../collection/collection";
4
+ import Store from "../store/store";
5
+ import Backup from "./backup";
6
+ export class DatabaseFileDriver {
7
+ name;
8
+ dbPath;
9
+ directory;
10
+ encrypted;
11
+ constructor({ name, dbPath, encrypted, }) {
12
+ this.name = name;
13
+ this.dbPath = dbPath;
14
+ this.directory = dbPath;
15
+ this.encrypted = encrypted;
16
+ }
17
+ get size() {
18
+ return this._getDirectorySize(this.directory);
19
+ }
20
+ create() {
21
+ if (!fs.existsSync(this.directory))
22
+ fs.mkdirSync(this.directory, { recursive: true });
23
+ }
24
+ delete() {
25
+ if (fs.existsSync(this.directory))
26
+ fs.rmSync(this.directory, { recursive: true, force: true });
27
+ }
28
+ reset() {
29
+ this.delete();
30
+ this.create();
31
+ }
32
+ backup(backupName) {
33
+ const backupDir = path.join(this.directory, "backups", backupName);
34
+ if (!fs.existsSync(backupDir))
35
+ fs.mkdirSync(backupDir, { recursive: true });
36
+ this._copyRecursive(this.directory, backupDir, ["backups"]);
37
+ return new Backup({
38
+ name: backupName,
39
+ databaseDirectory: this.directory,
40
+ });
41
+ }
42
+ removeBackup(backupName) {
43
+ const backupDir = path.join(this.directory, "backups", backupName);
44
+ if (fs.existsSync(backupDir)) {
45
+ fs.rmSync(backupDir, { recursive: true, force: true });
46
+ }
47
+ }
48
+ removeAllBackups() {
49
+ const backupsDir = path.join(this.directory, "backups");
50
+ if (fs.existsSync(backupsDir)) {
51
+ fs.rmSync(backupsDir, { recursive: true, force: true });
52
+ }
53
+ }
54
+ getBackups() {
55
+ const backupsDir = path.join(this.directory, "backups");
56
+ if (!fs.existsSync(backupsDir))
57
+ return [];
58
+ return fs
59
+ .readdirSync(backupsDir, { withFileTypes: true })
60
+ .filter((entry) => entry.isDirectory())
61
+ .map((entry) => new Backup({
62
+ name: entry.name,
63
+ databaseDirectory: this.directory,
64
+ }));
65
+ }
66
+ getCollections() {
67
+ const collectionsDir = path.join(this.directory, "collections");
68
+ if (!fs.existsSync(collectionsDir))
69
+ return [];
70
+ return fs
71
+ .readdirSync(collectionsDir, { withFileTypes: true })
72
+ .filter((entry) => entry.isDirectory())
73
+ .map((entry) => new Collection({
74
+ name: entry.name,
75
+ path: path.join(collectionsDir, entry.name),
76
+ encrypted: this.encrypted,
77
+ database: this,
78
+ }));
79
+ }
80
+ getStores() {
81
+ const storesDir = path.join(this.directory, "stores");
82
+ if (!fs.existsSync(storesDir))
83
+ return {};
84
+ return fs
85
+ .readdirSync(storesDir, { withFileTypes: true })
86
+ .filter((entry) => entry.isFile())
87
+ .reduce((acc, entry) => {
88
+ const name = entry.name;
89
+ const s = new Store({
90
+ name,
91
+ path: path.join(storesDir, name),
92
+ encrypted: this.encrypted,
93
+ });
94
+ s.create?.();
95
+ return acc;
96
+ }, {});
97
+ }
98
+ // --- Internal helpers ---
99
+ _getDirectorySize(dir) {
100
+ let total = 0;
101
+ if (!fs.existsSync(dir))
102
+ return 0;
103
+ const list = fs.readdirSync(dir, { withFileTypes: true });
104
+ for (const entry of list) {
105
+ const entryPath = path.join(dir, entry.name);
106
+ if (entry.isDirectory()) {
107
+ total += this._getDirectorySize(entryPath);
108
+ }
109
+ else if (entry.isFile()) {
110
+ total += fs.statSync(entryPath).size;
111
+ }
112
+ }
113
+ return total;
114
+ }
115
+ // Copy contents of the src directory to dest directory, skipping any folders named in excludeDirs.
116
+ _copyRecursive(src, dest, excludeDirs = []) {
117
+ if (!fs.existsSync(src))
118
+ return;
119
+ if (!fs.existsSync(dest))
120
+ fs.mkdirSync(dest, { recursive: true });
121
+ const items = fs.readdirSync(src, { withFileTypes: true });
122
+ for (const item of items) {
123
+ if (excludeDirs.includes(item.name))
124
+ continue;
125
+ const srcPath = path.join(src, item.name);
126
+ const destPath = path.join(dest, item.name);
127
+ if (item.isDirectory()) {
128
+ this._copyRecursive(srcPath, destPath, excludeDirs);
129
+ }
130
+ else if (item.isFile()) {
131
+ fs.copyFileSync(srcPath, destPath);
132
+ }
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,24 @@
1
+ export default class Store {
2
+ private _name;
3
+ private _storage;
4
+ constructor({ name, path, encrypted, secretKey, }: {
5
+ name: string;
6
+ path: string;
7
+ encrypted?: boolean;
8
+ secretKey?: string;
9
+ });
10
+ get name(): string;
11
+ create(): void;
12
+ set(key: string, value: any): any;
13
+ setFrom(key: string, func: (data: any) => any, fallback?: any): any;
14
+ has(key: string): boolean;
15
+ get(key: string): any;
16
+ remove(key: string): any;
17
+ all(): any;
18
+ clear(): any;
19
+ drop(): void;
20
+ get size(): number;
21
+ get sizeFormatted(): string;
22
+ toString(): string;
23
+ }
24
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/store/store.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,EACV,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,SAAS,GACV,EAAE;QACD,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;IASD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,IAAI,IAAI;IAId,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG;IAIjC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,GAAG;IAInE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAIrB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;IAIxB,GAAG,IAAI,GAAG;IAIV,KAAK,IAAI,GAAG;IAIZ,IAAI,IAAI,IAAI;IAKZ,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,QAAQ,IAAI,MAAM;CAGnB"}
@@ -0,0 +1,54 @@
1
+ import { Format } from "../../tools";
2
+ import StoreFileDriver from "./store_file_driver";
3
+ export default class Store {
4
+ _name;
5
+ _storage;
6
+ constructor({ name, path, encrypted, secretKey, }) {
7
+ this._name = name;
8
+ this._storage = new StoreFileDriver({
9
+ secretKey,
10
+ path,
11
+ encrypted,
12
+ });
13
+ }
14
+ get name() {
15
+ return this._name;
16
+ }
17
+ create() {
18
+ this._storage.create();
19
+ }
20
+ set(key, value) {
21
+ return this._storage.set(key, value);
22
+ }
23
+ setFrom(key, func, fallback) {
24
+ return this._storage.setFrom(key, func, fallback);
25
+ }
26
+ has(key) {
27
+ return this._storage.has(key);
28
+ }
29
+ get(key) {
30
+ return this._storage.get(key);
31
+ }
32
+ remove(key) {
33
+ return this._storage.remove(key);
34
+ }
35
+ all() {
36
+ return this._storage.readAll();
37
+ }
38
+ clear() {
39
+ return this._storage.clear();
40
+ }
41
+ drop() {
42
+ this._storage.delete();
43
+ }
44
+ // INFO
45
+ get size() {
46
+ return this._storage.size;
47
+ }
48
+ get sizeFormatted() {
49
+ return Format.sizeToHumanReadable(this.size);
50
+ }
51
+ toString() {
52
+ return `Store [ ${this._name} • ${this.sizeFormatted} • ${Object.keys(this.all()).length} keys ]`;
53
+ }
54
+ }