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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.md CHANGED
@@ -1,186 +1,253 @@
1
- # Chain DB - TS
1
+ # Chain DB TypeScript Client
2
2
 
3
- ChainDB TS is a library that allows the usage of the ChainDB database in TypeScript and JavaScript projects.
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.
4
4
 
5
- Chain DB is a Story-driven database. This new type of system uses some features used in blockchain technology. Each change generates a transaction that is saved in a block. The network works centrally, so persistent data is not decentralized.
5
+ ## Installation
6
6
 
7
- This database has some features by default, such as: create user account, get user account, transfer units and get transfer records as well as the main feature that is tables.
8
-
9
- The `unit` property present in each user's account can be anything the project wants, it can be a type of currency, item, resource.
10
-
11
- Visit the [Chain DB repository](https://github.com/wpdas/chain-db) to get to know more.
12
-
13
- ## Install
14
-
15
- Install using npm or yarn:
16
-
17
- ```sh
7
+ ```bash
18
8
  npm install chain-db-ts
19
-
20
9
  # or
21
-
22
10
  yarn add chain-db-ts
23
11
  ```
24
12
 
25
- ## Usage examples
13
+ ## Usage
26
14
 
27
- First of all, it's good to know that all requests return a `BasicResponse<D>` object that has the following structure:
15
+ ### Connecting to Chain DB
28
16
 
29
- **success:** `boolean` (informs if the transaction was successful) <br/>
30
- **error_msg:** `string` (error message) <br/>
31
- **data:** `D` (any expected data type depending on the request) <br/>
17
+ ```typescript
18
+ import { connect } from 'chain-db-ts'
32
19
 
33
- Make sure you have the database running on your local machine or use the server link from where the database is running.
20
+ // Connect to Chain DB
21
+ // Parameters: server | database | user | password
22
+ // If the server parameter is null, "http://localhost:2818" will be used as default
23
+ const db = await connect({
24
+ server: 'http://localhost:2818',
25
+ database: 'my-database',
26
+ user: 'root',
27
+ password: '1234',
28
+ })
29
+ ```
34
30
 
35
- ### Table
31
+ ### Working with Tables
36
32
 
37
- Tables must be simple class with default values, empty or not. This class will be used as a reference to create the table's fields.
33
+ Define your table structure using TypeScript interfaces:
38
34
 
39
- When it's time to persist the table's data on the chain, just call the `persit` database function.
35
+ ```typescript
36
+ // Define your table structure
37
+ interface GreetingTable {
38
+ greeting: string
39
+ }
40
40
 
41
- ```ts
42
- // Greeting Table
43
- class GreetingTable {
44
- public greeting = 'Hi'
41
+ // Define a more complex table
42
+ interface UserTable {
43
+ id: number
44
+ name: string
45
+ email: string
46
+ active: boolean
47
+ createdAt: string
45
48
  }
46
49
  ```
47
50
 
48
- ```ts
49
- import { connect } from 'chain-db-ts'
50
- import { GreetingTable } from './tables'
51
+ ### Getting a Table
51
52
 
52
- const main async () {
53
- // server | db-name | user | password
54
- // If the `server` parameter is empty(null), then "http://localhost:2818" will be used.
55
- const db = connect('http://localhost:2818', 'test-db', 'root', '1234')
53
+ ```typescript
54
+ // Get a table instance
55
+ // If the table already exists in the chain, its data will be loaded
56
+ const greetingTable = await db.getTable<GreetingTable>('greeting')
56
57
 
57
- // Initialize the "greeting" table using the "GreetingTable"
58
- // class as a template. If there is already any data saved in
59
- // the chain, this data will be populated in the table instance.
60
- const greetingTable = await db.get_table('greeting', new GreetingTable())
61
- console.log(greetingTable.table) // { greeting: 'Hi' }
58
+ // Access the table data
59
+ console.log(greetingTable.table) // e.g., { greeting: 'Hello' }
60
+ ```
62
61
 
63
- // Mutating data
64
- greetingTable.table.greeting = "Hello my dear!"
65
- await greetingTable.persist() // Data is persisted on the blockchain
62
+ ### Modifying and Persisting Data
66
63
 
67
- // See the most updated values of the table
68
- console.log(greetingTable.table) // { greeting: 'Hello my dear!' }
69
- }
70
- main()
64
+ ```typescript
65
+ // Modify the table data
66
+ greetingTable.table.greeting = 'Hello, Chain DB!'
67
+
68
+ // Persist changes to database (creates a new record)
69
+ await greetingTable.persist()
71
70
  ```
72
71
 
73
- The next examples will not include the `db` implementation, ` import` lines and the `const main async () {}` block as this is implied.
72
+ ### Updating the Last Item
74
73
 
75
- ### Create User Account
74
+ ```typescript
75
+ // Update the last item without creating a new one
76
+ greetingTable.table.greeting = 'Updated greeting'
77
+ await greetingTable.update()
78
+ ```
76
79
 
77
- This is a default database feature that allows you to create user accounts within the database. As these are hashed accounts, the only data required is: Username and Password. This data is hashed, that is, only the user with the correct data can access the data.
80
+ ### Getting Table History
78
81
 
79
- It is not possible to recover an account in which the user has forgotten access data.
82
+ ```typescript
83
+ // Get the last 100 changes to the table
84
+ const history = await greetingTable.getHistory(100)
85
+ console.log(history)
86
+ // Example output:
87
+ // [
88
+ // { greeting: 'Hello, Chain DB!' },
89
+ // { greeting: 'Hello' },
90
+ // { greeting: 'Hi there' },
91
+ // ...
92
+ // ]
93
+ ```
94
+
95
+ ### Real-time Events with WebSockets
96
+
97
+ Chain DB supports real-time updates through WebSockets. You can subscribe to table events to get notified when data changes:
98
+
99
+ ```typescript
100
+ import { EventTypes, EventData } from 'chain-db-ts'
101
+
102
+ // Subscribe to table update events
103
+ db.events().subscribe(EventTypes.TABLE_UPDATE, (eventData: EventData) => {
104
+ console.log('Table updated:', eventData.table)
105
+ console.log('New data:', eventData.data)
106
+ })
80
107
 
81
- ```ts
82
- const user_name = 'wenderson.fake'
83
- const user_pass = '1234'
108
+ // Subscribe to new data persistence events
109
+ db.events().subscribe(EventTypes.TABLE_PERSIST, (eventData: EventData) => {
110
+ console.log('New data added to table:', eventData.table)
111
+ console.log('Data:', eventData.data)
112
+ })
84
113
 
85
- // Check if the given name is already in use
86
- const user_name_taken = await db.check_user_name(user_name)
87
- if (!user_name_taken.success) {
88
- // user name | password | units (optional) | password hint (optional - may be used in the future versions)
89
- const user = await db.create_user_account(user_name, user_pass, 2)
90
- console.log(user.data)
91
- // {
92
- // id: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
93
- // user_name: 'wenderson.fake',
94
- // units: 2
95
- // }
114
+ // Unsubscribe from an event
115
+ const myCallback = (eventData: EventData) => {
116
+ // Handle event
96
117
  }
118
+ db.events().subscribe(EventTypes.TABLE_UPDATE, myCallback)
119
+ // Later, when you want to unsubscribe:
120
+ db.events().unsubscribe(EventTypes.TABLE_UPDATE, myCallback)
121
+
122
+ // Close WebSocket connection when done
123
+ db.events().closeEvents()
97
124
  ```
98
125
 
99
- ### Get User Account Info
126
+ The `EventData` object contains:
100
127
 
101
- This feature can be used for the "Login/Sign In" action.
128
+ - `event_type`: The type of event (TableUpdate, TablePersist)
129
+ - `database`: The database name
130
+ - `table`: The table name
131
+ - `data`: The data associated with the event
132
+ - `timestamp`: When the event occurred
102
133
 
103
- ```ts
104
- const user_name = 'wenderson.fake'
105
- const user_pass = '1234'
106
- const user = await db.get_user_account(user_name, user_pass)
107
- console.log(user.data)
108
- // {
109
- // id: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
110
- // user_name: 'wenderson.fake',
111
- // units: 2
112
- // }
113
- ```
134
+ ### Querying Data
114
135
 
115
- ### Get User Account Info By User Id
136
+ #### Basic Queries
116
137
 
117
- Just another way to fetch the user info.
138
+ ```typescript
139
+ // Find items with exact matches
140
+ const users = await userTable.findWhere(
141
+ { active: true, name: 'John' }, // criteria
142
+ 10, // limit (default: 1000)
143
+ true // reverse order (default: true)
144
+ )
145
+ ```
118
146
 
119
- ```ts
120
- const wenderson_id = 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3'
121
- const user = await db.get_user_account_by_id(wenderson_id)
122
- console.log(user.data)
123
- // {
124
- // id: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
125
- // user_name: 'wenderson.fake',
126
- // units: 2
127
- // }
147
+ #### Advanced Queries
148
+
149
+ ```typescript
150
+ import { Operators } from 'chain-db-ts'
151
+
152
+ // Find items with advanced criteria
153
+ const users = await userTable.findWhereAdvanced(
154
+ [
155
+ {
156
+ field: 'name',
157
+ operator: Operators.CONTAINS,
158
+ value: 'John',
159
+ },
160
+ {
161
+ field: 'age',
162
+ operator: Operators.GREATER_THAN,
163
+ value: 25,
164
+ },
165
+ ],
166
+ 10, // limit
167
+ true // reverse order
168
+ )
128
169
  ```
129
170
 
130
- ### Transfer Units Between Two Users
171
+ Available operators:
131
172
 
132
- As said before, `unit` property present in each user's account can be anything the project wants, it can be a type of currency, item, resource.
173
+ - `EQUAL` (==)
174
+ - `NOT_EQUAL` (!=)
175
+ - `GREATER_THAN` (>)
176
+ - `GREATER_THAN_OR_EQUAL` (>=)
177
+ - `LESS_THAN` (<)
178
+ - `LESS_THAN_OR_EQUAL` (<=)
179
+ - `CONTAINS` (for strings and arrays)
180
+ - `STARTS_WITH` (for strings)
181
+ - `ENDS_WITH` (for strings)
133
182
 
134
- Below is an example of user `wenderson` trying to send 2 units to `suly`:
183
+ ### Other Table Methods
135
184
 
136
- ```ts
137
- const wenderson_id = 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3'
138
- const suly_id = '136c406933d98e5c8bb4820f5145869bb5ad40647b768de4e9adb2a52d0dea2f'
185
+ ```typescript
186
+ // Check if a table is empty
187
+ const isEmpty = greetingTable.isEmpty()
139
188
 
140
- const wenderson_data = await db.get_user_account_by_id(wenderson_id)
141
- const units_to_transfer = 2
189
+ // Get the table name
190
+ const tableName = greetingTable.getName()
142
191
 
143
- if (wenderson_data.data!.units >= units_to_transfer) {
144
- const res = await db.transfer_units(wenderson_id, suly_id, units_to_transfer)
145
- console.log(res.success)
146
- // true / false
147
- }
192
+ // Refetch the table data from the database
193
+ await greetingTable.refetch()
148
194
  ```
149
195
 
150
- ### Fetching the Latest Units Transfer Record
196
+ ## Complete Example
151
197
 
152
- Use this feature to get the last unit transfer record involving a user.
198
+ ```typescript
199
+ import { connect, EventTypes, EventData } from 'chain-db-ts'
153
200
 
154
- ```ts
155
- const wenderson_id = 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3'
156
- const last_units_transference_record = await db.get_transfer_by_user_id(wenderson_id)
157
- console.log(last_units_transference_record.data)
158
- // {
159
- // from: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
160
- // to: '136c406933d98e5c8bb4820f5145869bb5ad40647b768de4e9adb2a52d0dea2f',
161
- // units: 2
162
- // }
163
- ```
201
+ // Define table structure
202
+ interface GreetingTable {
203
+ greeting: string
204
+ }
164
205
 
165
- ### Fetching All the Transfer of Units Records
206
+ async function main() {
207
+ // Connect to Chain DB
208
+ const db = await connect({
209
+ server: 'http://localhost:2818',
210
+ database: 'test-db',
211
+ user: 'root',
212
+ password: '1234',
213
+ })
214
+
215
+ // Get the "greeting" table
216
+ const greetingTable = await db.getTable<GreetingTable>('greeting')
217
+ console.log(greetingTable.table) // e.g., { greeting: 'Hi' }
218
+
219
+ // Subscribe to table update events
220
+ db.events().subscribe(EventTypes.TABLE_UPDATE, (eventData: EventData) => {
221
+ if (eventData.table === 'greeting') {
222
+ console.log('Greeting table updated:', eventData.data)
223
+ }
224
+ })
225
+
226
+ // Modify and persist data
227
+ greetingTable.table.greeting = 'Hello my dear!'
228
+ await greetingTable.persist() // Data is persisted on database
229
+
230
+ // See the updated values
231
+ console.log(greetingTable.table) // { greeting: 'Hello my dear!' }
166
232
 
167
- Use this feature to get the last unit transfer record involving a user.
233
+ // Get the last 100 changes
234
+ const greetingHistory = await greetingTable.getHistory(100)
235
+ console.log(greetingHistory)
236
+ // [
237
+ // { greeting: 'Hello my dear!' },
238
+ // { greeting: 'Hi' },
239
+ // { greeting: 'Ei, sou eu :D' },
240
+ // { greeting: 'Heyo' },
241
+ // ...
242
+ // ]
243
+
244
+ // Close WebSocket connection when done
245
+ db.events().closeEvents()
246
+ }
168
247
 
169
- ```ts
170
- const wenderson_id = 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3'
171
- const all_units_transfers_record = await db.get_all_transfers_by_user_id(wenderson_id)
172
- console.log(all_units_transfers_record.data)
173
- // [
174
- // {
175
- // from: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
176
- // to: '136c406933d98e5c8bb4820f5145869bb5ad40647b768de4e9adb2a52d0dea2f',
177
- // units: 2
178
- // },
179
- // {
180
- // from: '136c406933d98e5c8bb4820f5145869bb5ad40647b768de4e9adb2a52d0dea2f',
181
- // to: 'b2e4e7c15f733d8c18836ffd22051ed855226d9041fb9452f17f498fc2bcbce3',
182
- // units: 6
183
- // },
184
- // ...
185
- // ]
248
+ main().catch(console.error)
186
249
  ```
250
+
251
+ ## License
252
+
253
+ MIT
@@ -1,6 +0,0 @@
1
- export declare class Access {
2
- user: string;
3
- password: string;
4
- constructor(user: string, password: string);
5
- parse: (data_base: string, table_name: string) => string;
6
- }
@@ -1,22 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- exports.__esModule = true;
6
- exports.Access = void 0;
7
- var sha256_1 = __importDefault(require("sha256"));
8
- var Access = /** @class */ (function () {
9
- function Access(user, password) {
10
- var _this = this;
11
- this.user = '';
12
- this.password = '';
13
- this.parse = function (data_base, table_name) {
14
- var access_info = "".concat(data_base).concat(table_name).concat(_this.user).concat(_this.password);
15
- return (0, sha256_1["default"])(access_info);
16
- };
17
- this.user = user;
18
- this.password = password;
19
- }
20
- return Access;
21
- }());
22
- exports.Access = Access;
@@ -1,6 +0,0 @@
1
- export declare class Access {
2
- user: string;
3
- password: string;
4
- constructor(user: string, password: string);
5
- parse: (data_base: string, table_name: string) => string;
6
- }
@@ -1,16 +0,0 @@
1
- import sha256 from 'sha256';
2
- var Access = /** @class */ (function () {
3
- function Access(user, password) {
4
- var _this = this;
5
- this.user = '';
6
- this.password = '';
7
- this.parse = function (data_base, table_name) {
8
- var access_info = "".concat(data_base).concat(table_name).concat(_this.user).concat(_this.password);
9
- return sha256(access_info);
10
- };
11
- this.user = user;
12
- this.password = password;
13
- }
14
- return Access;
15
- }());
16
- export { Access };