chain-db-ts 1.0.0-rc.1 → 1.0.0-rc.3

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/CHANGELOG.md ADDED
@@ -0,0 +1,116 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.0.0-rc.3] - 2025-03-11
6
+
7
+ ### Changed
8
+
9
+ - Added support to older version while using the `getCurrentDocId()` method.
10
+
11
+ ## [1.0.0-rc.2] - 2025-03-05
12
+
13
+ ### Added
14
+
15
+ - New `TableDoc` interface for working with specific documents
16
+ - Added `refetch()` method to `TableDoc` to get the latest document data
17
+ - Added `getTableName()` method to `TableDoc` to get the table name
18
+ - Added `isEmpty()` method to `TableDoc` to check if the document is empty
19
+ - Added `DocId<Model>` type that adds a readonly `doc_id` property to models
20
+ - Added `getCurrentDocId()` method to `Table` to get the current document ID
21
+ - The `persist()` method now returns the created document with its `doc_id`
22
+ - Document IDs are now accessible directly via `doc_id` property in both `Table` and `TableDoc` instances
23
+
24
+ ### Changed
25
+
26
+ - **BREAKING CHANGE**: Renamed `table` property to `currentDoc` in `Table` class for better semantics
27
+ - Improved error messages with more details about the operation and error
28
+ - Enhanced type safety with the `DocId<Model>` type
29
+
30
+ ### Removed
31
+
32
+ - **BREAKING CHANGE**: Removed `update()` method from `Table` class
33
+ - To update documents, you must now use `getDoc()` to get a document reference and then call `update()` on that reference
34
+ - This change prevents accidental creation of duplicate records and makes the API more intuitive
35
+
36
+ ### Migration Guide
37
+
38
+ #### Property Renaming
39
+
40
+ Before:
41
+
42
+ ```typescript
43
+ // Accessing table data
44
+ console.log(greetingTable.table)
45
+
46
+ // Accessing document data from TableDoc
47
+ console.log(specificDoc.table)
48
+ ```
49
+
50
+ After:
51
+
52
+ ```typescript
53
+ // Accessing current document data from Table
54
+ console.log(greetingTable.currentDoc)
55
+
56
+ // Accessing document data from TableDoc
57
+ console.log(specificDoc.doc)
58
+ ```
59
+
60
+ #### Updating Documents
61
+
62
+ Before:
63
+
64
+ ```typescript
65
+ // Update the last item
66
+ greetingTable.table.greeting = 'Updated greeting'
67
+ await greetingTable.update()
68
+
69
+ // Update a specific document by ID
70
+ greetingTable.table.greeting = 'Updated specific document'
71
+ await greetingTable.update('550e8400-e29b-41d4-a716-446655440000')
72
+ ```
73
+
74
+ After:
75
+
76
+ ```typescript
77
+ // Get a specific document by ID
78
+ const specificDoc = await greetingTable.getDoc('550e8400-e29b-41d4-a716-446655440000')
79
+
80
+ // Update the document
81
+ specificDoc.doc.greeting = 'Updated greeting'
82
+ await specificDoc.update()
83
+
84
+ // Optionally, refetch the document to get the latest data
85
+ await specificDoc.refetch()
86
+ ```
87
+
88
+ #### Accessing Document IDs
89
+
90
+ New in this version:
91
+
92
+ ```typescript
93
+ // When persisting data, you get the document ID in the result
94
+ const result = await greetingTable.persist()
95
+ console.log(result.doc_id) // The ID of the newly created document
96
+
97
+ // You can also get the current document ID directly from the table
98
+ const currentDocId = greetingTable.getCurrentDocId()
99
+
100
+ // When working with a specific document, the ID is available in multiple ways
101
+ const specificDoc = await greetingTable.getDoc(docId)
102
+ console.log(specificDoc.doc_id) // From the TableDoc instance
103
+ console.log(specificDoc.doc.doc_id) // From the document object
104
+ ```
105
+
106
+ ## [1.0.0-rc.1] - 2025-03-01
107
+
108
+ Initial release candidate.
109
+
110
+ ### Added
111
+
112
+ - Type-safe API with TypeScript generics
113
+ - Promise-based API with async/await
114
+ - WebSocket support for real-time updates
115
+ - Advanced query capabilities
116
+ - Complete history access
@@ -2,9 +2,10 @@ export declare const DEFAULT_API_SERVER = "http://localhost:2818";
2
2
  export declare const API_BASE = "/api/v1";
3
3
  export declare const CONNECT: string;
4
4
  export declare const GET_TABLE: (table: string) => string;
5
- export declare const UPDATE_LAST_ITEM: (table: string) => string;
5
+ export declare const UPDATE_ITEM: (table: string) => string;
6
6
  export declare const PERSIST_NEW_DATA: (table: string) => string;
7
7
  export declare const GET_HISTORY: (table: string, limit?: number) => string;
8
8
  export declare const FIND_WHERE_BASIC: (table: string) => string;
9
9
  export declare const FIND_WHERE_ADVANCED: (table: string) => string;
10
+ export declare const GET_DOC: (table: string, doc_id: string) => string;
10
11
  export declare const WEB_SOCKET_EVENTS: string;
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
- exports.WEB_SOCKET_EVENTS = exports.FIND_WHERE_ADVANCED = exports.FIND_WHERE_BASIC = exports.GET_HISTORY = exports.PERSIST_NEW_DATA = exports.UPDATE_LAST_ITEM = exports.GET_TABLE = exports.CONNECT = exports.API_BASE = exports.DEFAULT_API_SERVER = void 0;
3
+ exports.WEB_SOCKET_EVENTS = exports.GET_DOC = exports.FIND_WHERE_ADVANCED = exports.FIND_WHERE_BASIC = exports.GET_HISTORY = exports.PERSIST_NEW_DATA = exports.UPDATE_ITEM = exports.GET_TABLE = exports.CONNECT = exports.API_BASE = exports.DEFAULT_API_SERVER = void 0;
4
4
  // Contants
5
5
  exports.DEFAULT_API_SERVER = 'http://localhost:2818';
6
6
  exports.API_BASE = '/api/v1';
7
7
  exports.CONNECT = "".concat(exports.API_BASE, "/database/connect");
8
8
  var GET_TABLE = function (table) { return "".concat(exports.API_BASE, "/table/").concat(table); };
9
9
  exports.GET_TABLE = GET_TABLE;
10
- var UPDATE_LAST_ITEM = function (table) { return "".concat(exports.API_BASE, "/table/").concat(table, "/update"); };
11
- exports.UPDATE_LAST_ITEM = UPDATE_LAST_ITEM;
10
+ var UPDATE_ITEM = function (table) { return "".concat(exports.API_BASE, "/table/").concat(table, "/update"); };
11
+ exports.UPDATE_ITEM = UPDATE_ITEM;
12
12
  var PERSIST_NEW_DATA = function (table) { return "".concat(exports.API_BASE, "/table/").concat(table, "/persist"); };
13
13
  exports.PERSIST_NEW_DATA = PERSIST_NEW_DATA;
14
14
  var GET_HISTORY = function (table, limit) {
@@ -20,4 +20,6 @@ var FIND_WHERE_BASIC = function (table) { return "".concat(exports.API_BASE, "/t
20
20
  exports.FIND_WHERE_BASIC = FIND_WHERE_BASIC;
21
21
  var FIND_WHERE_ADVANCED = function (table) { return "".concat(exports.API_BASE, "/table/").concat(table, "/find-advanced"); };
22
22
  exports.FIND_WHERE_ADVANCED = FIND_WHERE_ADVANCED;
23
+ var GET_DOC = function (table, doc_id) { return "".concat(exports.API_BASE, "/table/").concat(table, "/doc/").concat(doc_id); };
24
+ exports.GET_DOC = GET_DOC;
23
25
  exports.WEB_SOCKET_EVENTS = "".concat(exports.API_BASE, "/events");
@@ -0,0 +1,37 @@
1
+ import { ChainDB } from './chain-db';
2
+ import { DocId, TableDoc } from './types';
3
+ /**
4
+ * Implementation of TableDoc interface
5
+ * Represents a specific document from a table
6
+ */
7
+ export declare class TableDocImpl<Model> implements TableDoc<Model> {
8
+ /**
9
+ * The document data
10
+ */
11
+ doc: DocId<Model>;
12
+ /**
13
+ * The document ID
14
+ */
15
+ private doc_id;
16
+ private tableName;
17
+ private db;
18
+ constructor(tableName: string, doc_id: string, data: DocId<Model>, db: ChainDB);
19
+ /**
20
+ * Update the document data
21
+ * This will update the specific document without creating a new one
22
+ */
23
+ update(): Promise<void>;
24
+ /**
25
+ * Refetch the document data from the database
26
+ * Useful when the document might have been updated by another application
27
+ */
28
+ refetch(): Promise<void>;
29
+ /**
30
+ * Get the table name this document belongs to
31
+ */
32
+ getTableName(): string;
33
+ /**
34
+ * Check if the table is empty
35
+ */
36
+ isEmpty(): boolean;
37
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ exports.__esModule = true;
42
+ exports.TableDocImpl = void 0;
43
+ var axios_1 = __importDefault(require("axios"));
44
+ var constants_1 = require("./constants");
45
+ var utils_1 = require("./utils");
46
+ /**
47
+ * Implementation of TableDoc interface
48
+ * Represents a specific document from a table
49
+ */
50
+ var TableDocImpl = /** @class */ (function () {
51
+ function TableDocImpl(tableName, doc_id, data, db) {
52
+ this.tableName = tableName;
53
+ this.doc_id = doc_id;
54
+ this.doc = data;
55
+ this.db = db;
56
+ }
57
+ /**
58
+ * Update the document data
59
+ * This will update the specific document without creating a new one
60
+ */
61
+ TableDocImpl.prototype.update = function () {
62
+ return __awaiter(this, void 0, void 0, function () {
63
+ var url, body, response, e_1;
64
+ return __generator(this, function (_a) {
65
+ switch (_a.label) {
66
+ case 0:
67
+ url = "".concat(this.db.server).concat((0, constants_1.UPDATE_ITEM)(this.tableName));
68
+ body = {
69
+ data: this.doc,
70
+ doc_id: this.doc_id
71
+ };
72
+ _a.label = 1;
73
+ case 1:
74
+ _a.trys.push([1, 3, , 4]);
75
+ return [4 /*yield*/, (0, utils_1.post)(url, body, this.db.auth)];
76
+ case 2:
77
+ response = _a.sent();
78
+ if (!response.data.success) {
79
+ throw new Error(response.data.message);
80
+ }
81
+ return [3 /*break*/, 4];
82
+ case 3:
83
+ e_1 = _a.sent();
84
+ throw new Error("Something went wrong updating document ".concat(this.doc_id, ": ").concat(e_1.message || String(e_1)));
85
+ case 4: return [2 /*return*/];
86
+ }
87
+ });
88
+ });
89
+ };
90
+ /**
91
+ * Refetch the document data from the database
92
+ * Useful when the document might have been updated by another application
93
+ */
94
+ TableDocImpl.prototype.refetch = function () {
95
+ return __awaiter(this, void 0, void 0, function () {
96
+ var url, response, e_2;
97
+ return __generator(this, function (_a) {
98
+ switch (_a.label) {
99
+ case 0:
100
+ url = "".concat(this.db.server).concat((0, constants_1.GET_DOC)(this.tableName, this.doc_id));
101
+ _a.label = 1;
102
+ case 1:
103
+ _a.trys.push([1, 3, , 4]);
104
+ return [4 /*yield*/, axios_1["default"].get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
105
+ case 2:
106
+ response = _a.sent();
107
+ if (!response.data.success) {
108
+ throw new Error(response.data.message);
109
+ }
110
+ // Update the table data with the latest data from the database
111
+ this.doc = response.data.data;
112
+ return [3 /*break*/, 4];
113
+ case 3:
114
+ e_2 = _a.sent();
115
+ throw new Error("Something went wrong refetching document ".concat(this.doc_id, ": ").concat(e_2.message || String(e_2)));
116
+ case 4: return [2 /*return*/];
117
+ }
118
+ });
119
+ });
120
+ };
121
+ /**
122
+ * Get the table name this document belongs to
123
+ */
124
+ TableDocImpl.prototype.getTableName = function () {
125
+ return this.tableName;
126
+ };
127
+ /**
128
+ * Check if the table is empty
129
+ */
130
+ TableDocImpl.prototype.isEmpty = function () {
131
+ return Object.keys(this.doc).length === 0;
132
+ };
133
+ return TableDocImpl;
134
+ }());
135
+ exports.TableDocImpl = TableDocImpl;
@@ -1,25 +1,23 @@
1
1
  import { ChainDB } from './chain-db';
2
- import { Criteria, CriteriaAdvanced } from './types';
2
+ import { Criteria, CriteriaAdvanced, DocId, TableDoc } from './types';
3
3
  declare class Table<Model> {
4
- table: Model;
4
+ /**
5
+ * The current document data
6
+ */
7
+ currentDoc: Model;
5
8
  private name;
6
9
  private db;
7
10
  constructor(name: string, db: ChainDB);
8
11
  /**
9
- * Persist table data changes
10
- */
11
- persist(): Promise<void>;
12
- /**
13
- * Update data of the last table's item (or create a new item if there is none).
14
- * This ensures that no new item is created.
12
+ * Persist table's document data changes
15
13
  */
16
- update(): Promise<void>;
14
+ persist(): Promise<DocId<Model>>;
17
15
  /**
18
16
  * Get the history of changes. A list of transactions from the most recent to the most old
19
17
  * in a range of depth
20
18
  * @param limit
21
19
  */
22
- getHistory(limit: number): Promise<Model[]>;
20
+ getHistory(limit: number): Promise<DocId<Model>[]>;
23
21
  /**
24
22
  * Refetch the table data
25
23
  */
@@ -52,7 +50,7 @@ declare class Table<Model> {
52
50
  * score: 100
53
51
  * })
54
52
  */
55
- findWhere(criteria: Criteria<Model>, limit?: number, reverse?: boolean): Promise<Model[]>;
53
+ findWhere(criteria: Criteria<Model>, limit?: number, reverse?: boolean): Promise<DocId<Model>[]>;
56
54
  /**
57
55
  * Find items in the table using advanced criteria with operators
58
56
  * @param criteria Array of criteria to filter items. Each criteria contains:
@@ -81,6 +79,16 @@ declare class Table<Model> {
81
79
  * }
82
80
  * ])
83
81
  */
84
- findWhereAdvanced(criteria: CriteriaAdvanced<Model>[], limit?: number, reverse?: boolean): Promise<Model[]>;
82
+ findWhereAdvanced(criteria: CriteriaAdvanced<Model>[], limit?: number, reverse?: boolean): Promise<DocId<Model>[]>;
83
+ /**
84
+ * Get the current document ID
85
+ */
86
+ getCurrentDocId(): string;
87
+ /**
88
+ * Get a specific document by its ID
89
+ * @param doc_id The document ID to retrieve
90
+ * @returns A TableDoc instance with the specific document data
91
+ */
92
+ getDoc(doc_id: string): Promise<TableDoc<Model>>;
85
93
  }
86
94
  export default Table;
@@ -42,15 +42,16 @@ exports.__esModule = true;
42
42
  var axios_1 = __importDefault(require("axios"));
43
43
  var constants_1 = require("./constants");
44
44
  var utils_1 = require("./utils");
45
+ var table_doc_1 = require("./table-doc");
45
46
  var Table = /** @class */ (function () {
46
47
  function Table(name, db) {
47
48
  this.name = '';
48
- this.table = {};
49
+ this.currentDoc = {};
49
50
  this.name = name;
50
51
  this.db = db;
51
52
  }
52
53
  /**
53
- * Persist table data changes
54
+ * Persist table's document data changes
54
55
  */
55
56
  Table.prototype.persist = function () {
56
57
  return __awaiter(this, void 0, void 0, function () {
@@ -60,7 +61,7 @@ var Table = /** @class */ (function () {
60
61
  case 0:
61
62
  url = "".concat(this.db.server).concat((0, constants_1.PERSIST_NEW_DATA)(this.name));
62
63
  body = {
63
- data: this.table
64
+ data: this.currentDoc
64
65
  };
65
66
  _a.label = 1;
66
67
  case 1:
@@ -71,7 +72,7 @@ var Table = /** @class */ (function () {
71
72
  if (!response.data.success) {
72
73
  throw new Error(response.data.message);
73
74
  }
74
- return [3 /*break*/, 4];
75
+ return [2 /*return*/, response.data.data];
75
76
  case 3:
76
77
  e_1 = _a.sent();
77
78
  throw new Error("Something went wrong with persist operation: ".concat(e_1.message || String(e_1)));
@@ -80,38 +81,6 @@ var Table = /** @class */ (function () {
80
81
  });
81
82
  });
82
83
  };
83
- /**
84
- * Update data of the last table's item (or create a new item if there is none).
85
- * This ensures that no new item is created.
86
- */
87
- Table.prototype.update = function () {
88
- return __awaiter(this, void 0, void 0, function () {
89
- var url, body, response, e_2;
90
- return __generator(this, function (_a) {
91
- switch (_a.label) {
92
- case 0:
93
- url = "".concat(this.db.server).concat((0, constants_1.UPDATE_LAST_ITEM)(this.name));
94
- body = {
95
- data: this.table
96
- };
97
- _a.label = 1;
98
- case 1:
99
- _a.trys.push([1, 3, , 4]);
100
- return [4 /*yield*/, (0, utils_1.post)(url, body, this.db.auth)];
101
- case 2:
102
- response = _a.sent();
103
- if (!response.data.success) {
104
- throw new Error(response.data.message);
105
- }
106
- return [3 /*break*/, 4];
107
- case 3:
108
- e_2 = _a.sent();
109
- throw new Error("Something went wrong with update operation: ".concat(e_2.message || String(e_2)));
110
- case 4: return [2 /*return*/];
111
- }
112
- });
113
- });
114
- };
115
84
  /**
116
85
  * Get the history of changes. A list of transactions from the most recent to the most old
117
86
  * in a range of depth
@@ -119,7 +88,7 @@ var Table = /** @class */ (function () {
119
88
  */
120
89
  Table.prototype.getHistory = function (limit) {
121
90
  return __awaiter(this, void 0, void 0, function () {
122
- var url, response, e_3;
91
+ var url, response, e_2;
123
92
  return __generator(this, function (_a) {
124
93
  switch (_a.label) {
125
94
  case 0:
@@ -136,8 +105,8 @@ var Table = /** @class */ (function () {
136
105
  // Return data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
137
106
  return [2 /*return*/, response.data.data];
138
107
  case 3:
139
- e_3 = _a.sent();
140
- throw new Error("Something went wrong with getHistory operation: ".concat(e_3.message || String(e_3)));
108
+ e_2 = _a.sent();
109
+ throw new Error("Something went wrong with getHistory operation: ".concat(e_2.message || String(e_2)));
141
110
  case 4: return [2 /*return*/];
142
111
  }
143
112
  });
@@ -148,7 +117,7 @@ var Table = /** @class */ (function () {
148
117
  */
149
118
  Table.prototype.refetch = function () {
150
119
  return __awaiter(this, void 0, void 0, function () {
151
- var url, response, e_4;
120
+ var url, response, e_3;
152
121
  return __generator(this, function (_a) {
153
122
  switch (_a.label) {
154
123
  case 0:
@@ -159,11 +128,11 @@ var Table = /** @class */ (function () {
159
128
  return [4 /*yield*/, axios_1["default"].get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
160
129
  case 2:
161
130
  response = _a.sent();
162
- this.table = response.data.data ? response.data.data : {};
131
+ this.currentDoc = response.data.data ? response.data.data : {};
163
132
  return [3 /*break*/, 4];
164
133
  case 3:
165
- e_4 = _a.sent();
166
- throw new Error("Something went wrong with refetch operation: ".concat(e_4.message || String(e_4)));
134
+ e_3 = _a.sent();
135
+ throw new Error("Something went wrong with refetch operation: ".concat(e_3.message || String(e_3)));
167
136
  case 4: return [2 /*return*/];
168
137
  }
169
138
  });
@@ -173,7 +142,7 @@ var Table = /** @class */ (function () {
173
142
  * Check if the table is empty
174
143
  */
175
144
  Table.prototype.isEmpty = function () {
176
- return Object.keys(this.table).length === 0;
145
+ return Object.keys(this.currentDoc).length === 0;
177
146
  };
178
147
  /**
179
148
  * Get the table's name
@@ -205,7 +174,7 @@ var Table = /** @class */ (function () {
205
174
  if (limit === void 0) { limit = 1000; }
206
175
  if (reverse === void 0) { reverse = true; }
207
176
  return __awaiter(this, void 0, void 0, function () {
208
- var url, body, response, e_5;
177
+ var url, body, response, e_4;
209
178
  return __generator(this, function (_a) {
210
179
  switch (_a.label) {
211
180
  case 0:
@@ -227,14 +196,13 @@ var Table = /** @class */ (function () {
227
196
  // Return found data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
228
197
  return [2 /*return*/, response.data.data];
229
198
  case 3:
230
- e_5 = _a.sent();
231
- throw new Error("Something went wrong with findWhere operation: ".concat(e_5.message || String(e_5)));
199
+ e_4 = _a.sent();
200
+ throw new Error("Something went wrong with findWhere operation: ".concat(e_4.message || String(e_4)));
232
201
  case 4: return [2 /*return*/];
233
202
  }
234
203
  });
235
204
  });
236
205
  };
237
- // TODO: Implement documentation
238
206
  /**
239
207
  * Find items in the table using advanced criteria with operators
240
208
  * @param criteria Array of criteria to filter items. Each criteria contains:
@@ -267,7 +235,7 @@ var Table = /** @class */ (function () {
267
235
  if (limit === void 0) { limit = 1000; }
268
236
  if (reverse === void 0) { reverse = true; }
269
237
  return __awaiter(this, void 0, void 0, function () {
270
- var url, body, response, e_6;
238
+ var url, body, response, e_5;
271
239
  return __generator(this, function (_a) {
272
240
  switch (_a.label) {
273
241
  case 0:
@@ -288,9 +256,48 @@ var Table = /** @class */ (function () {
288
256
  }
289
257
  // Return found data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
290
258
  return [2 /*return*/, response.data.data];
259
+ case 3:
260
+ e_5 = _a.sent();
261
+ throw new Error("Something went wrong with findWhereAdvanced operation: ".concat(e_5.message || String(e_5)));
262
+ case 4: return [2 /*return*/];
263
+ }
264
+ });
265
+ });
266
+ };
267
+ /**
268
+ * Get the current document ID
269
+ */
270
+ Table.prototype.getCurrentDocId = function () {
271
+ var _doc = this.currentDoc;
272
+ // Support to applications using older versions
273
+ return _doc.doc_id ? _doc.doc_id : '';
274
+ };
275
+ /**
276
+ * Get a specific document by its ID
277
+ * @param doc_id The document ID to retrieve
278
+ * @returns A TableDoc instance with the specific document data
279
+ */
280
+ Table.prototype.getDoc = function (doc_id) {
281
+ return __awaiter(this, void 0, void 0, function () {
282
+ var url, response, e_6;
283
+ return __generator(this, function (_a) {
284
+ switch (_a.label) {
285
+ case 0:
286
+ url = "".concat(this.db.server).concat((0, constants_1.GET_DOC)(this.name, doc_id));
287
+ _a.label = 1;
288
+ case 1:
289
+ _a.trys.push([1, 3, , 4]);
290
+ return [4 /*yield*/, axios_1["default"].get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
291
+ case 2:
292
+ response = _a.sent();
293
+ if (!response.data.success) {
294
+ throw new Error(response.data.message);
295
+ }
296
+ // Create a TableDoc instance with the document data
297
+ return [2 /*return*/, new table_doc_1.TableDocImpl(this.name, doc_id, response.data.data, this.db)];
291
298
  case 3:
292
299
  e_6 = _a.sent();
293
- throw new Error("Something went wrong with findWhereAdvanced operation: ".concat(e_6.message || String(e_6)));
300
+ throw new Error("Something went wrong with getDoc operation: ".concat(e_6.message || String(e_6)));
294
301
  case 4: return [2 /*return*/];
295
302
  }
296
303
  });
@@ -51,3 +51,37 @@ export type EventData = {
51
51
  timestamp: number;
52
52
  };
53
53
  export type EventCallback = (data: EventData) => void;
54
+ /**
55
+ * Represents a specific document from a table
56
+ * Contains only the necessary methods to work with a specific document
57
+ */
58
+ export interface TableDoc<Model> {
59
+ /**
60
+ * The document data
61
+ */
62
+ doc: DocId<Model>;
63
+ /**
64
+ * Update the document data
65
+ * This will update the specific document without creating a new one
66
+ */
67
+ update(): Promise<void>;
68
+ /**
69
+ * Get the table name this document belongs to
70
+ */
71
+ getTableName(): string;
72
+ /**
73
+ * Refetch the document data from the database
74
+ * Useful when the document might have been updated by another application
75
+ */
76
+ refetch(): Promise<void>;
77
+ /**
78
+ * Check if the document is empty
79
+ */
80
+ isEmpty(): boolean;
81
+ }
82
+ export type DocId<Model> = Model & {
83
+ /**
84
+ * The document ID (unique identifier). Immutable.
85
+ */
86
+ readonly doc_id: string;
87
+ };
@@ -1,2 +1,4 @@
1
1
  export { ChainDB, connect } from './features/chain-db';
2
- export { BasicResponse, Operators, CriteriaAdvanced, Criteria, EventTypes, EventData, EventCallback, } from './features/types';
2
+ export { BasicResponse, Operators, CriteriaAdvanced, Criteria, TableDoc, EventTypes, EventData, EventCallback, } from './features/types';
3
+ export { default as Events } from './features/events';
4
+ export { TableDocImpl } from './features/table-doc';
package/dist/cjs/index.js CHANGED
@@ -11,10 +11,14 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
11
11
  o[k2] = m[k];
12
12
  }));
13
13
  exports.__esModule = true;
14
- exports.EventTypes = exports.Operators = exports.connect = exports.ChainDB = void 0;
14
+ exports.TableDocImpl = exports.Events = exports.EventTypes = exports.Operators = exports.connect = exports.ChainDB = void 0;
15
15
  var chain_db_1 = require("./features/chain-db");
16
16
  __createBinding(exports, chain_db_1, "ChainDB");
17
17
  __createBinding(exports, chain_db_1, "connect");
18
18
  var types_1 = require("./features/types");
19
19
  __createBinding(exports, types_1, "Operators");
20
20
  __createBinding(exports, types_1, "EventTypes");
21
+ var events_1 = require("./features/events");
22
+ __createBinding(exports, events_1, "default", "Events");
23
+ var table_doc_1 = require("./features/table-doc");
24
+ __createBinding(exports, table_doc_1, "TableDocImpl");
@@ -2,9 +2,10 @@ export declare const DEFAULT_API_SERVER = "http://localhost:2818";
2
2
  export declare const API_BASE = "/api/v1";
3
3
  export declare const CONNECT: string;
4
4
  export declare const GET_TABLE: (table: string) => string;
5
- export declare const UPDATE_LAST_ITEM: (table: string) => string;
5
+ export declare const UPDATE_ITEM: (table: string) => string;
6
6
  export declare const PERSIST_NEW_DATA: (table: string) => string;
7
7
  export declare const GET_HISTORY: (table: string, limit?: number) => string;
8
8
  export declare const FIND_WHERE_BASIC: (table: string) => string;
9
9
  export declare const FIND_WHERE_ADVANCED: (table: string) => string;
10
+ export declare const GET_DOC: (table: string, doc_id: string) => string;
10
11
  export declare const WEB_SOCKET_EVENTS: string;