@tblabs/storage 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/IRepo.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  export interface IRepo<T> {
2
2
  Ping(): Promise<boolean>;
3
- Delete(folder: string, id: string): Promise<void>;
4
- Update(folder: string, id: string, item: T): Promise<void>;
3
+ Add(folder: string, id: string, item: T): Promise<void>;
4
+ GetAll(folder: string): Promise<T[]>;
5
5
  GetOne(folder: string, id: string): Promise<T | null>;
6
6
  FindOne(id: string): Promise<T | null>;
7
- GetAll(folder: string): Promise<T[]>;
8
7
  GetAllIds(folder: string): Promise<string[]>;
8
+ Update(folder: string, id: string, item: T): Promise<void>;
9
+ Delete(folder: string, id: string): Promise<void>;
9
10
  Move(id: string, sourceFolder: string, targetFolder: string): Promise<void>;
10
11
  Drop(): Promise<void>;
11
12
  }
@@ -0,0 +1,4 @@
1
+ import { Message } from '../MessageBus/Message';
2
+ export declare class AddCommand extends Message {
3
+ constructor(Id: string, Folder: string, Content: object);
4
+ }
@@ -0,0 +1,12 @@
1
+ import { Message } from '../MessageBus/Message';
2
+ export class AddCommand extends Message {
3
+ constructor(Id, Folder, Content) {
4
+ if (!Id) {
5
+ throw new Error(`Id not specified!`);
6
+ }
7
+ if (!Folder) {
8
+ throw new Error(`Folder not specified!`);
9
+ }
10
+ super("Add", { Id, Folder, Content });
11
+ }
12
+ }
@@ -0,0 +1,4 @@
1
+ import { Message } from '../MessageBus/Message';
2
+ export declare class AddDirCommand extends Message {
3
+ constructor(Folder: string);
4
+ }
@@ -0,0 +1,6 @@
1
+ import { Message } from '../MessageBus/Message';
2
+ export class AddDirCommand extends Message {
3
+ constructor(Folder) {
4
+ super("AddDir", { Folder });
5
+ }
6
+ }
package/OnlineRepo.d.ts CHANGED
@@ -1,18 +1,22 @@
1
1
  import { IRepo } from "./IRepo";
2
- import { MessageBus } from "./MessageBus/MessageBus";
2
+ import { ISender } from "./MessageBus/ISender";
3
3
  export declare class OnlineRepo<T extends object> implements IRepo<T> {
4
- private _bus;
5
- private storageFolder;
4
+ private server;
5
+ private databaseFolder;
6
+ private user;
6
7
  LOG: boolean;
7
- constructor(_bus: MessageBus, storageFolder: string);
8
+ private readonly _bus;
9
+ constructor(server: string, databaseFolder: string, user: ISender);
8
10
  private Log;
9
11
  Ping(): Promise<boolean>;
10
12
  GetOne(folder: string, id: string): Promise<T | null>;
11
13
  FindOne(id: string): Promise<T | null>;
12
14
  GetAll(folder: string): Promise<T[]>;
13
15
  GetAllIds(folder: string): Promise<string[]>;
16
+ Add(folder: string, id: string, item: T): Promise<void>;
14
17
  Update(folder: string, id: string, item: T): Promise<void>;
15
18
  Delete(folder: string, id: string): Promise<void>;
16
19
  Drop(): Promise<void>;
17
20
  Move(id: string, sourceFolder: string, targetFolder: string): Promise<void>;
21
+ AddDir(targetFolder: string): Promise<void>;
18
22
  }
package/OnlineRepo.js CHANGED
@@ -5,13 +5,20 @@ import { ListQuery } from "./Messages/ListQuery";
5
5
  import { MoveCommand } from "./Messages/MoveCommand";
6
6
  import { ReadQuery } from "./Messages/ReadQuery";
7
7
  import { UpdateCommand } from "./Messages/UpdateCommand";
8
+ import { MessageBus } from "./MessageBus/MessageBus";
9
+ import { AddCommand } from "./Messages/AddCommand";
10
+ import { AddDirCommand } from "./Messages/AddDirCommand";
8
11
  export class OnlineRepo {
9
- _bus;
10
- storageFolder;
12
+ server;
13
+ databaseFolder;
14
+ user;
11
15
  LOG = false;
12
- constructor(_bus, storageFolder) {
13
- this._bus = _bus;
14
- this.storageFolder = storageFolder;
16
+ _bus;
17
+ constructor(server, databaseFolder, user) {
18
+ this.server = server;
19
+ this.databaseFolder = databaseFolder;
20
+ this.user = user;
21
+ this._bus = new MessageBus(server, user);
15
22
  }
16
23
  Log(...message) {
17
24
  if (this.LOG)
@@ -22,7 +29,7 @@ export class OnlineRepo {
22
29
  }
23
30
  async GetOne(folder, id) {
24
31
  this.Log(`Fetching "${id}"...`);
25
- const folderPath = this.storageFolder + "/" + folder;
32
+ const folderPath = this.databaseFolder + "/" + folder;
26
33
  const queryResult = await this._bus.SendMessage(new ReadQuery(id, folderPath));
27
34
  if (queryResult.IsSuccess) {
28
35
  const item = queryResult.Result;
@@ -33,8 +40,8 @@ export class OnlineRepo {
33
40
  return null;
34
41
  }
35
42
  async FindOne(id) {
36
- this.Log(`Fetching "${id}"...`);
37
- const queryResult = await this._bus.SendMessage(new FindQuery(id, this.storageFolder));
43
+ this.Log(`Searching for "${id}"...`);
44
+ const queryResult = await this._bus.SendMessage(new FindQuery(id, this.databaseFolder));
38
45
  if (queryResult.IsSuccess) {
39
46
  const item = queryResult.Result;
40
47
  this.Log(`Found "${id}".`);
@@ -44,8 +51,8 @@ export class OnlineRepo {
44
51
  return null;
45
52
  }
46
53
  async GetAll(folder) {
47
- this.Log(`Fetching all from "${this.storageFolder}"...`);
48
- const folderPath = this.storageFolder + "/" + folder;
54
+ this.Log(`Fetching all from "${this.databaseFolder}"...`);
55
+ const folderPath = this.databaseFolder + "/" + folder;
49
56
  const queryResult = await this._bus.SendMessage(new ListQuery(folderPath, true));
50
57
  if (queryResult.IsSuccess) {
51
58
  const items = queryResult.Result;
@@ -56,8 +63,8 @@ export class OnlineRepo {
56
63
  throw new Error(`Could not fetch all from "${folder}": ${queryResult.ErrorMessage}`);
57
64
  }
58
65
  async GetAllIds(folder) {
59
- this.Log(`Fetching all from "${this.storageFolder}"...`);
60
- const folderPath = this.storageFolder + "/" + folder;
66
+ this.Log(`Fetching all ids from "${this.databaseFolder}"...`);
67
+ const folderPath = this.databaseFolder + "/" + folder;
61
68
  const queryResult = await this._bus.SendMessage(new ListQuery(folderPath, false));
62
69
  if (queryResult.IsSuccess) {
63
70
  const itemsIds = Object.values(queryResult.Result);
@@ -67,17 +74,26 @@ export class OnlineRepo {
67
74
  else
68
75
  throw new Error(`Could not fetch all ids from "${folder}": ${queryResult.ErrorMessage}`);
69
76
  }
77
+ async Add(folder, id, item) {
78
+ this.Log(`Adding "${id}" to "${folder}"...`);
79
+ const folderPath = this.databaseFolder + "/" + folder;
80
+ const result = await this._bus.SendMessage(new AddCommand(id, folderPath, item));
81
+ if (!result.IsSuccess)
82
+ throw new Error(`Could not add "${id}" to "${folderPath}": ${result.ErrorMessage}`);
83
+ this.Log(`"${id}" added to "${folderPath}".`);
84
+ }
85
+ ;
70
86
  async Update(folder, id, item) {
71
87
  this.Log(`Updating "${id}"...`);
72
- const folderPath = this.storageFolder + "/" + folder;
88
+ const folderPath = this.databaseFolder + "/" + folder;
73
89
  const result = await this._bus.SendMessage(new UpdateCommand(id, folderPath, item));
74
90
  if (!result.IsSuccess)
75
91
  throw new Error(`Could not update "${id}" in "${folderPath}": ${result.ErrorMessage}`);
76
- this.Log(`Updated "${id}" in "${folderPath}".`);
92
+ this.Log(`"${id}" updated in "${folderPath}".`);
77
93
  }
78
94
  ;
79
95
  async Delete(folder, id) {
80
- const folderPath = this.storageFolder + "/" + folder;
96
+ const folderPath = this.databaseFolder + "/" + folder;
81
97
  this.Log(`Deleting "${id}" from "${folderPath}"...`);
82
98
  const result = await this._bus.SendMessage(new DeleteCommand(id, folderPath));
83
99
  if (!result.IsSuccess)
@@ -85,19 +101,27 @@ export class OnlineRepo {
85
101
  this.Log(`Deleted "${id}" from "${folderPath}".`);
86
102
  }
87
103
  async Drop() {
88
- this.Log(`Dropping "${this.storageFolder}"...`);
89
- const result = await this._bus.SendMessage(new DropCommand(this.storageFolder));
104
+ this.Log(`Dropping "${this.databaseFolder}"...`);
105
+ const result = await this._bus.SendMessage(new DropCommand(this.databaseFolder));
90
106
  if (!result.IsSuccess)
91
- throw new Error(`Could not drop "${this.storageFolder}": ${result.ErrorMessage}`);
92
- this.Log(`Dropped "${this.storageFolder}".`);
107
+ throw new Error(`Could not drop "${this.databaseFolder}": ${result.ErrorMessage}`);
108
+ this.Log(`Dropped "${this.databaseFolder}".`);
93
109
  }
94
110
  async Move(id, sourceFolder, targetFolder) {
95
- const source = this.storageFolder + "/" + sourceFolder;
96
- const target = this.storageFolder + "/" + targetFolder;
111
+ const source = this.databaseFolder + "/" + sourceFolder;
112
+ const target = this.databaseFolder + "/" + targetFolder;
97
113
  this.Log(`Moving "${id}" from "${source}" to "${target}"...`);
98
114
  const result = await this._bus.SendMessage(new MoveCommand(id, source, target));
99
115
  if (!result.IsSuccess)
100
116
  throw new Error(`Could not move "${id}" from "${source}" to "${target}": ${result.ErrorMessage}`);
101
117
  this.Log(`Moved "${id}" from "${source}" to "${target}".`);
102
118
  }
119
+ async AddDir(targetFolder) {
120
+ const target = this.databaseFolder + "/" + targetFolder;
121
+ this.Log(`Adding directory "${target}"...`);
122
+ const result = await this._bus.SendMessage(new AddDirCommand(target));
123
+ if (!result.IsSuccess)
124
+ throw new Error(`Could not add directory "${target}": ${result.ErrorMessage}`);
125
+ this.Log(`Added directory "${target}".`);
126
+ }
103
127
  }
@@ -0,0 +1,11 @@
1
+ export declare abstract class RefConverter<R, T> {
2
+ protected abstract ConvertToRaw(obj: T): R | null;
3
+ protected abstract ConvertFromRaw(raw: R): T | null;
4
+ ToRaw(target: T): R | null;
5
+ FromRaw(raw: R): T | null;
6
+ protected GetArray<R, T>(value: R[], creator: (raw: R) => T): Array<T>;
7
+ protected GetString(value: any): string;
8
+ protected GetNumber(value: any): number;
9
+ protected GetBool(value: any): boolean;
10
+ protected GetDate(date: any): Date;
11
+ }
@@ -0,0 +1,36 @@
1
+ export class RefConverter {
2
+ ToRaw(target) {
3
+ try {
4
+ return this.ConvertToRaw(target);
5
+ }
6
+ catch (ex) {
7
+ console.error(`Conversion from object to raw problem: ${ex.message}\n\nStack trace: ${ex.stack}\n\nObject:`, target);
8
+ return null;
9
+ }
10
+ }
11
+ FromRaw(raw) {
12
+ try {
13
+ return this.ConvertFromRaw(raw);
14
+ }
15
+ catch (ex) {
16
+ console.error(`Conversion from raw to object problem: ${ex.message}\n\nStack trace: ${ex.stack}\n\nRaw:`, raw);
17
+ return null;
18
+ }
19
+ }
20
+ GetArray(value, creator) {
21
+ const items = value?.map(x => creator(x));
22
+ return items || [];
23
+ }
24
+ GetString(value) {
25
+ return value || "";
26
+ }
27
+ GetNumber(value) {
28
+ return +value || 0;
29
+ }
30
+ GetBool(value) {
31
+ return !!value || false;
32
+ }
33
+ GetDate(date) {
34
+ return date ? new Date(date) : new Date(0);
35
+ }
36
+ }
@@ -0,0 +1 @@
1
+ export declare function Delay(ms: number): Promise<unknown>;
package/Utils/Delay.js ADDED
@@ -0,0 +1,3 @@
1
+ export function Delay(ms) {
2
+ return new Promise(resolve => setTimeout(resolve, ms));
3
+ }
@@ -0,0 +1,3 @@
1
+ export declare class OperationRepeater {
2
+ RepeatTillSuccess(actionName: string, action: () => Promise<boolean>, attempts?: number, delay?: number): Promise<boolean>;
3
+ }
@@ -0,0 +1,19 @@
1
+ import { Delay } from "./Delay";
2
+ export class OperationRepeater {
3
+ async RepeatTillSuccess(actionName, action, attempts = 5, delay = 3000) {
4
+ for (let i = 1; i <= attempts; i++) {
5
+ console.log(i == 1 ? `Starting "${actionName}"...` : `Retrying (attempt ${i}/${attempts})...`);
6
+ const result = await action();
7
+ if (result == true) {
8
+ console.log(`Operation "${actionName}" completed successfully.`);
9
+ return true;
10
+ }
11
+ else {
12
+ console.log(`Operation "${actionName}" failed. Next attempt in ${i * delay}ms...`);
13
+ await Delay(i * delay);
14
+ }
15
+ }
16
+ console.log(`Could not complete "${actionName}" after ${attempts} attempts. Operation failed.`);
17
+ return false;
18
+ }
19
+ }
package/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from "./IRepo";
2
2
  export * from "./OnlineRepo";
3
+ export * from "./Utils/OperationRepeater";
4
+ export * from "./RefConverter";
package/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from "./IRepo";
2
2
  export * from "./OnlineRepo";
3
+ export * from "./Utils/OperationRepeater";
4
+ export * from "./RefConverter";
package/package.json CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "@tblabs/storage",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "online storage module",
5
5
  "license": "beerware",
6
6
  "main": "index.js",
7
7
  "types": "index.d.ts",
8
8
  "scripts": {
9
- "pack": "npm pack",
10
- "clean": "rm ./bin -rf",
9
+ "pack": "cd ./bin && npm pack",
10
+ "clean": "rm ./bin -rf && rm *.tgz -rf",
11
11
  "build": "npm run clean && tsc ./src/index.ts --declaration --outDir ./bin && cp ./package.json ./bin/package.json",
12
- "publish": "npm run build && npm run pack && cd ./bin && npm publish --access public"
12
+ "publish": "npm login && npm run build && npm run pack && cd ./bin && npm publish --access public"
13
13
  },
14
14
  "devDependencies": {
15
+ "@types/jest": "^30.0.0",
16
+ "@types/node": "^25.6.0",
17
+ "jest": "^30.3.0",
18
+ "ts-jest": "^29.4.9",
15
19
  "typescript": "^6.0.2"
16
20
  }
17
21
  }
Binary file