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.
@@ -3,7 +3,7 @@ export var DEFAULT_API_SERVER = 'http://localhost:2818';
3
3
  export var API_BASE = '/api/v1';
4
4
  export var CONNECT = "".concat(API_BASE, "/database/connect");
5
5
  export var GET_TABLE = function (table) { return "".concat(API_BASE, "/table/").concat(table); };
6
- export var UPDATE_LAST_ITEM = function (table) { return "".concat(API_BASE, "/table/").concat(table, "/update"); };
6
+ export var UPDATE_ITEM = function (table) { return "".concat(API_BASE, "/table/").concat(table, "/update"); };
7
7
  export var PERSIST_NEW_DATA = function (table) { return "".concat(API_BASE, "/table/").concat(table, "/persist"); };
8
8
  export var GET_HISTORY = function (table, limit) {
9
9
  if (limit === void 0) { limit = 25; }
@@ -11,4 +11,5 @@ export var GET_HISTORY = function (table, limit) {
11
11
  };
12
12
  export var FIND_WHERE_BASIC = function (table) { return "".concat(API_BASE, "/table/").concat(table, "/find"); };
13
13
  export var FIND_WHERE_ADVANCED = function (table) { return "".concat(API_BASE, "/table/").concat(table, "/find-advanced"); };
14
+ export var GET_DOC = function (table, doc_id) { return "".concat(API_BASE, "/table/").concat(table, "/doc/").concat(doc_id); };
14
15
  export var WEB_SOCKET_EVENTS = "".concat(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,129 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ 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;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import axios from 'axios';
38
+ import { UPDATE_ITEM, GET_DOC } from './constants';
39
+ import { post } from './utils';
40
+ /**
41
+ * Implementation of TableDoc interface
42
+ * Represents a specific document from a table
43
+ */
44
+ var TableDocImpl = /** @class */ (function () {
45
+ function TableDocImpl(tableName, doc_id, data, db) {
46
+ this.tableName = tableName;
47
+ this.doc_id = doc_id;
48
+ this.doc = data;
49
+ this.db = db;
50
+ }
51
+ /**
52
+ * Update the document data
53
+ * This will update the specific document without creating a new one
54
+ */
55
+ TableDocImpl.prototype.update = function () {
56
+ return __awaiter(this, void 0, void 0, function () {
57
+ var url, body, response, e_1;
58
+ return __generator(this, function (_a) {
59
+ switch (_a.label) {
60
+ case 0:
61
+ url = "".concat(this.db.server).concat(UPDATE_ITEM(this.tableName));
62
+ body = {
63
+ data: this.doc,
64
+ doc_id: this.doc_id
65
+ };
66
+ _a.label = 1;
67
+ case 1:
68
+ _a.trys.push([1, 3, , 4]);
69
+ return [4 /*yield*/, post(url, body, this.db.auth)];
70
+ case 2:
71
+ response = _a.sent();
72
+ if (!response.data.success) {
73
+ throw new Error(response.data.message);
74
+ }
75
+ return [3 /*break*/, 4];
76
+ case 3:
77
+ e_1 = _a.sent();
78
+ throw new Error("Something went wrong updating document ".concat(this.doc_id, ": ").concat(e_1.message || String(e_1)));
79
+ case 4: return [2 /*return*/];
80
+ }
81
+ });
82
+ });
83
+ };
84
+ /**
85
+ * Refetch the document data from the database
86
+ * Useful when the document might have been updated by another application
87
+ */
88
+ TableDocImpl.prototype.refetch = function () {
89
+ return __awaiter(this, void 0, void 0, function () {
90
+ var url, response, e_2;
91
+ return __generator(this, function (_a) {
92
+ switch (_a.label) {
93
+ case 0:
94
+ url = "".concat(this.db.server).concat(GET_DOC(this.tableName, this.doc_id));
95
+ _a.label = 1;
96
+ case 1:
97
+ _a.trys.push([1, 3, , 4]);
98
+ return [4 /*yield*/, axios.get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
99
+ case 2:
100
+ response = _a.sent();
101
+ if (!response.data.success) {
102
+ throw new Error(response.data.message);
103
+ }
104
+ // Update the table data with the latest data from the database
105
+ this.doc = response.data.data;
106
+ return [3 /*break*/, 4];
107
+ case 3:
108
+ e_2 = _a.sent();
109
+ throw new Error("Something went wrong refetching document ".concat(this.doc_id, ": ").concat(e_2.message || String(e_2)));
110
+ case 4: return [2 /*return*/];
111
+ }
112
+ });
113
+ });
114
+ };
115
+ /**
116
+ * Get the table name this document belongs to
117
+ */
118
+ TableDocImpl.prototype.getTableName = function () {
119
+ return this.tableName;
120
+ };
121
+ /**
122
+ * Check if the table is empty
123
+ */
124
+ TableDocImpl.prototype.isEmpty = function () {
125
+ return Object.keys(this.doc).length === 0;
126
+ };
127
+ return TableDocImpl;
128
+ }());
129
+ export { 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;
package/features/table.js CHANGED
@@ -35,17 +35,18 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  }
36
36
  };
37
37
  import axios from 'axios';
38
- import { FIND_WHERE_ADVANCED, FIND_WHERE_BASIC, GET_HISTORY, GET_TABLE, PERSIST_NEW_DATA, UPDATE_LAST_ITEM, } from './constants';
38
+ import { FIND_WHERE_ADVANCED, FIND_WHERE_BASIC, GET_HISTORY, GET_TABLE, PERSIST_NEW_DATA, GET_DOC } from './constants';
39
39
  import { post } from './utils';
40
+ import { TableDocImpl } from './table-doc';
40
41
  var Table = /** @class */ (function () {
41
42
  function Table(name, db) {
42
43
  this.name = '';
43
- this.table = {};
44
+ this.currentDoc = {};
44
45
  this.name = name;
45
46
  this.db = db;
46
47
  }
47
48
  /**
48
- * Persist table data changes
49
+ * Persist table's document data changes
49
50
  */
50
51
  Table.prototype.persist = function () {
51
52
  return __awaiter(this, void 0, void 0, function () {
@@ -55,7 +56,7 @@ var Table = /** @class */ (function () {
55
56
  case 0:
56
57
  url = "".concat(this.db.server).concat(PERSIST_NEW_DATA(this.name));
57
58
  body = {
58
- data: this.table
59
+ data: this.currentDoc
59
60
  };
60
61
  _a.label = 1;
61
62
  case 1:
@@ -66,7 +67,7 @@ var Table = /** @class */ (function () {
66
67
  if (!response.data.success) {
67
68
  throw new Error(response.data.message);
68
69
  }
69
- return [3 /*break*/, 4];
70
+ return [2 /*return*/, response.data.data];
70
71
  case 3:
71
72
  e_1 = _a.sent();
72
73
  throw new Error("Something went wrong with persist operation: ".concat(e_1.message || String(e_1)));
@@ -75,38 +76,6 @@ var Table = /** @class */ (function () {
75
76
  });
76
77
  });
77
78
  };
78
- /**
79
- * Update data of the last table's item (or create a new item if there is none).
80
- * This ensures that no new item is created.
81
- */
82
- Table.prototype.update = function () {
83
- return __awaiter(this, void 0, void 0, function () {
84
- var url, body, response, e_2;
85
- return __generator(this, function (_a) {
86
- switch (_a.label) {
87
- case 0:
88
- url = "".concat(this.db.server).concat(UPDATE_LAST_ITEM(this.name));
89
- body = {
90
- data: this.table
91
- };
92
- _a.label = 1;
93
- case 1:
94
- _a.trys.push([1, 3, , 4]);
95
- return [4 /*yield*/, post(url, body, this.db.auth)];
96
- case 2:
97
- response = _a.sent();
98
- if (!response.data.success) {
99
- throw new Error(response.data.message);
100
- }
101
- return [3 /*break*/, 4];
102
- case 3:
103
- e_2 = _a.sent();
104
- throw new Error("Something went wrong with update operation: ".concat(e_2.message || String(e_2)));
105
- case 4: return [2 /*return*/];
106
- }
107
- });
108
- });
109
- };
110
79
  /**
111
80
  * Get the history of changes. A list of transactions from the most recent to the most old
112
81
  * in a range of depth
@@ -114,7 +83,7 @@ var Table = /** @class */ (function () {
114
83
  */
115
84
  Table.prototype.getHistory = function (limit) {
116
85
  return __awaiter(this, void 0, void 0, function () {
117
- var url, response, e_3;
86
+ var url, response, e_2;
118
87
  return __generator(this, function (_a) {
119
88
  switch (_a.label) {
120
89
  case 0:
@@ -131,8 +100,8 @@ var Table = /** @class */ (function () {
131
100
  // Return data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
132
101
  return [2 /*return*/, response.data.data];
133
102
  case 3:
134
- e_3 = _a.sent();
135
- throw new Error("Something went wrong with getHistory operation: ".concat(e_3.message || String(e_3)));
103
+ e_2 = _a.sent();
104
+ throw new Error("Something went wrong with getHistory operation: ".concat(e_2.message || String(e_2)));
136
105
  case 4: return [2 /*return*/];
137
106
  }
138
107
  });
@@ -143,7 +112,7 @@ var Table = /** @class */ (function () {
143
112
  */
144
113
  Table.prototype.refetch = function () {
145
114
  return __awaiter(this, void 0, void 0, function () {
146
- var url, response, e_4;
115
+ var url, response, e_3;
147
116
  return __generator(this, function (_a) {
148
117
  switch (_a.label) {
149
118
  case 0:
@@ -154,11 +123,11 @@ var Table = /** @class */ (function () {
154
123
  return [4 /*yield*/, axios.get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
155
124
  case 2:
156
125
  response = _a.sent();
157
- this.table = response.data.data ? response.data.data : {};
126
+ this.currentDoc = response.data.data ? response.data.data : {};
158
127
  return [3 /*break*/, 4];
159
128
  case 3:
160
- e_4 = _a.sent();
161
- throw new Error("Something went wrong with refetch operation: ".concat(e_4.message || String(e_4)));
129
+ e_3 = _a.sent();
130
+ throw new Error("Something went wrong with refetch operation: ".concat(e_3.message || String(e_3)));
162
131
  case 4: return [2 /*return*/];
163
132
  }
164
133
  });
@@ -168,7 +137,7 @@ var Table = /** @class */ (function () {
168
137
  * Check if the table is empty
169
138
  */
170
139
  Table.prototype.isEmpty = function () {
171
- return Object.keys(this.table).length === 0;
140
+ return Object.keys(this.currentDoc).length === 0;
172
141
  };
173
142
  /**
174
143
  * Get the table's name
@@ -200,7 +169,7 @@ var Table = /** @class */ (function () {
200
169
  if (limit === void 0) { limit = 1000; }
201
170
  if (reverse === void 0) { reverse = true; }
202
171
  return __awaiter(this, void 0, void 0, function () {
203
- var url, body, response, e_5;
172
+ var url, body, response, e_4;
204
173
  return __generator(this, function (_a) {
205
174
  switch (_a.label) {
206
175
  case 0:
@@ -222,14 +191,13 @@ var Table = /** @class */ (function () {
222
191
  // Return found data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
223
192
  return [2 /*return*/, response.data.data];
224
193
  case 3:
225
- e_5 = _a.sent();
226
- throw new Error("Something went wrong with findWhere operation: ".concat(e_5.message || String(e_5)));
194
+ e_4 = _a.sent();
195
+ throw new Error("Something went wrong with findWhere operation: ".concat(e_4.message || String(e_4)));
227
196
  case 4: return [2 /*return*/];
228
197
  }
229
198
  });
230
199
  });
231
200
  };
232
- // TODO: Implement documentation
233
201
  /**
234
202
  * Find items in the table using advanced criteria with operators
235
203
  * @param criteria Array of criteria to filter items. Each criteria contains:
@@ -262,7 +230,7 @@ var Table = /** @class */ (function () {
262
230
  if (limit === void 0) { limit = 1000; }
263
231
  if (reverse === void 0) { reverse = true; }
264
232
  return __awaiter(this, void 0, void 0, function () {
265
- var url, body, response, e_6;
233
+ var url, body, response, e_5;
266
234
  return __generator(this, function (_a) {
267
235
  switch (_a.label) {
268
236
  case 0:
@@ -283,9 +251,48 @@ var Table = /** @class */ (function () {
283
251
  }
284
252
  // Return found data. Only table fields, e.g.: [{fieldA: 'Hi', filedB: 22}]
285
253
  return [2 /*return*/, response.data.data];
254
+ case 3:
255
+ e_5 = _a.sent();
256
+ throw new Error("Something went wrong with findWhereAdvanced operation: ".concat(e_5.message || String(e_5)));
257
+ case 4: return [2 /*return*/];
258
+ }
259
+ });
260
+ });
261
+ };
262
+ /**
263
+ * Get the current document ID
264
+ */
265
+ Table.prototype.getCurrentDocId = function () {
266
+ var _doc = this.currentDoc;
267
+ // Support to applications using older versions
268
+ return _doc.doc_id ? _doc.doc_id : '';
269
+ };
270
+ /**
271
+ * Get a specific document by its ID
272
+ * @param doc_id The document ID to retrieve
273
+ * @returns A TableDoc instance with the specific document data
274
+ */
275
+ Table.prototype.getDoc = function (doc_id) {
276
+ return __awaiter(this, void 0, void 0, function () {
277
+ var url, response, e_6;
278
+ return __generator(this, function (_a) {
279
+ switch (_a.label) {
280
+ case 0:
281
+ url = "".concat(this.db.server).concat(GET_DOC(this.name, doc_id));
282
+ _a.label = 1;
283
+ case 1:
284
+ _a.trys.push([1, 3, , 4]);
285
+ return [4 /*yield*/, axios.get(url, { headers: { Authorization: "Basic ".concat(this.db.auth) } })];
286
+ case 2:
287
+ response = _a.sent();
288
+ if (!response.data.success) {
289
+ throw new Error(response.data.message);
290
+ }
291
+ // Create a TableDoc instance with the document data
292
+ return [2 /*return*/, new TableDocImpl(this.name, doc_id, response.data.data, this.db)];
286
293
  case 3:
287
294
  e_6 = _a.sent();
288
- throw new Error("Something went wrong with findWhereAdvanced operation: ".concat(e_6.message || String(e_6)));
295
+ throw new Error("Something went wrong with getDoc operation: ".concat(e_6.message || String(e_6)));
289
296
  case 4: return [2 /*return*/];
290
297
  }
291
298
  });
@@ -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
+ };
package/index.d.ts CHANGED
@@ -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/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export { ChainDB, connect } from './features/chain-db';
2
2
  export { Operators, EventTypes, } from './features/types';
3
+ export { default as Events } from './features/events';
4
+ export { TableDocImpl } from './features/table-doc';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chain-db-ts",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "Chain DB Client for Javascript/Typescript Node apps.",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./index.js",
package/readme.md CHANGED
@@ -1,6 +1,6 @@
1
- # Chain DB TypeScript Client
1
+ # Chain DB TS / JS Client (Node)
2
2
 
3
- A TypeScript client for [Chain DB](https://github.com/wpdas/chain-db), a simple database that maintains a history of changes, allowing you to track how your data evolves over time.
3
+ A TypeScript / JavaScript client for [Chain DB](https://github.com/wpdas/chain-db), a secure database system with built-in history tracking, offering AES-256-GCM encryption, atomic operations with rollback capability, and automatic backups.
4
4
 
5
5
  ## Installation
6
6
 
@@ -52,31 +52,70 @@ interface UserTable {
52
52
 
53
53
  ```typescript
54
54
  // Get a table instance
55
- // If the table already exists in the chain, its data will be loaded
55
+ // If the table already exists in the chain, its data will be loaded. (data from the last record stored in the table)
56
56
  const greetingTable = await db.getTable<GreetingTable>('greeting')
57
57
 
58
- // Access the table data
59
- console.log(greetingTable.table) // e.g., { greeting: 'Hello' }
58
+ // Access the current document data (the last record stored in the table)
59
+ console.log(greetingTable.currentDoc) // e.g., { greeting: 'Hello' }
60
60
  ```
61
61
 
62
62
  ### Modifying and Persisting Data
63
63
 
64
64
  ```typescript
65
- // Modify the table data
66
- greetingTable.table.greeting = 'Hello, Chain DB!'
65
+ // Modify the current document data
66
+ greetingTable.currentDoc.greeting = 'Hello, Chain DB!'
67
67
 
68
- // Persist changes to database (creates a new record)
69
- await greetingTable.persist()
68
+ // Persist changes to database (creates a new record with a new doc_id)
69
+ const result = await greetingTable.persist()
70
+
71
+ // The persist method returns the created document with its doc_id
72
+ console.log(result.doc_id) // e.g., '550e8400-e29b-41d4-a716-446655440000'
73
+
74
+ // You can also access the current document's ID directly
75
+ const currentDocId = greetingTable.getCurrentDocId()
76
+ console.log(currentDocId) // Same as result.doc_id
70
77
  ```
71
78
 
72
- ### Updating the Last Item
79
+ ### Updating Item
73
80
 
74
81
  ```typescript
75
- // Update the last item without creating a new one
76
- greetingTable.table.greeting = 'Updated greeting'
77
- await greetingTable.update()
82
+ // To update a specific document, first get it by ID
83
+ const docId = '550e8400-e29b-41d4-a716-446655440000'
84
+ const specificDoc = await greetingTable.getDoc(docId)
85
+
86
+ // Then update its data
87
+ specificDoc.doc.greeting = 'Updated greeting'
88
+ await specificDoc.update()
78
89
  ```
79
90
 
91
+ ### Getting a Specific Document
92
+
93
+ ```typescript
94
+ // Get a specific document by its ID (assuming we know a document ID)
95
+ // The document ID is generated by ChainDB when data is persisted
96
+ const docId = '550e8400-e29b-41d4-a716-446655440000' // Example ID
97
+ const specificDoc = await greetingTable.getDoc(docId)
98
+
99
+ // Access the document data
100
+ console.log(specificDoc.doc) // e.g., { greeting: 'Hello from specific doc', doc_id: '550e8400-e29b-41d4-a716-446655440000' }
101
+
102
+ // The doc_id is also available directly in the document object
103
+ console.log(specificDoc.doc.doc_id) // '550e8400-e29b-41d4-a716-446655440000'
104
+
105
+ // Update the specific document
106
+ specificDoc.doc.greeting = 'Updated greeting for specific doc'
107
+ await specificDoc.update() // Updates only this specific document
108
+
109
+ // Refetch the document data if it might have been updated elsewhere
110
+ await specificDoc.refetch()
111
+ console.log(specificDoc.doc) // Updated data from the database
112
+
113
+ // Get the table name this document belongs to
114
+ const tableName = specificDoc.getTableName() // 'greeting'
115
+ ```
116
+
117
+ Note: The `TableDoc` instance returned by `getDoc()` is a simplified version of a table that only allows updating the specific document. It cannot create new records with `persist()` or perform other table operations.
118
+
80
119
  ### Getting Table History
81
120
 
82
121
  ```typescript
@@ -214,7 +253,7 @@ async function main() {
214
253
 
215
254
  // Get the "greeting" table
216
255
  const greetingTable = await db.getTable<GreetingTable>('greeting')
217
- console.log(greetingTable.table) // e.g., { greeting: 'Hi' }
256
+ console.log(greetingTable.currentDoc) // e.g., { greeting: 'Hi' }
218
257
 
219
258
  // Subscribe to table update events
220
259
  db.events().subscribe(EventTypes.TABLE_UPDATE, (eventData: EventData) => {
@@ -224,20 +263,42 @@ async function main() {
224
263
  })
225
264
 
226
265
  // Modify and persist data
227
- greetingTable.table.greeting = 'Hello my dear!'
228
- await greetingTable.persist() // Data is persisted on database
266
+ greetingTable.currentDoc.greeting = 'Hello my dear!'
267
+ const persistResult = await greetingTable.persist() // Data is persisted on database
268
+
269
+ // Get the doc_id of the newly created document
270
+ console.log('New document ID:', persistResult.doc_id)
271
+
272
+ // You can also get the current document ID directly from the table
273
+ const currentDocId = greetingTable.getCurrentDocId()
274
+ console.log('Current document ID:', currentDocId)
229
275
 
230
276
  // See the updated values
231
- console.log(greetingTable.table) // { greeting: 'Hello my dear!' }
277
+ console.log(greetingTable.currentDoc) // { greeting: 'Hello my dear!', doc_id: '...' }
278
+
279
+ // Get a specific document by its ID
280
+ // We can use the ID we just got from the persist operation
281
+ const specificDoc = await greetingTable.getDoc(currentDocId)
282
+
283
+ // Access the document data and ID
284
+ console.log(specificDoc.doc) // { greeting: 'Hello my dear!', doc_id: '...' }
285
+ console.log(specificDoc.doc.doc_id) // Same as currentDocId
286
+
287
+ // Update a specific document
288
+ specificDoc.doc.greeting = 'Updated specific document'
289
+ await specificDoc.update() // Updates only this specific document
290
+
291
+ // Refetch the document to get the latest data
292
+ await specificDoc.refetch()
293
+ console.log(specificDoc.doc) // Latest data from the database
232
294
 
233
295
  // Get the last 100 changes
234
296
  const greetingHistory = await greetingTable.getHistory(100)
235
297
  console.log(greetingHistory)
236
298
  // [
299
+ // { greeting: 'Updated specific document' },
237
300
  // { greeting: 'Hello my dear!' },
238
301
  // { greeting: 'Hi' },
239
- // { greeting: 'Ei, sou eu :D' },
240
- // { greeting: 'Heyo' },
241
302
  // ...
242
303
  // ]
243
304