presidium-db-client-server 0.0.0-stage → 0.1.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/ArrayEventEmitter.js +21 -0
- package/AsyncIterator.js +38 -0
- package/BinaryEntriesStream.js +75 -0
- package/BinaryStream.js +54 -0
- package/DatabaseHandler.js +292 -0
- package/DatabaseServer.js +101 -0
- package/DiskHashTableClient.js +224 -0
- package/DiskSortedHashTableClient.js +321 -0
- package/README.md +54 -2
- package/TextEntriesStream.js +73 -0
- package/TextStream.js +55 -0
- package/buffersToEntry.js +44 -0
- package/handleServerResponse.js +72 -0
- package/package.json +45 -4
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presidium DB Client and Server may be freely distributed under the CFOSS license.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
require("rubico/global")
|
|
6
|
+
const HTTP = require("presidium/HTTP")
|
|
7
|
+
const Readable = require("presidium/Readable")
|
|
8
|
+
const handleServerResponse = require("./handleServerResponse")
|
|
9
|
+
const buffersToEntry = require("./buffersToEntry")
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @name DiskHashTableClient
|
|
13
|
+
*
|
|
14
|
+
* @docs
|
|
15
|
+
* ```specscript
|
|
16
|
+
* new DiskHashTableClient(options {
|
|
17
|
+
* serverUrl: string,
|
|
18
|
+
* tableName: string,
|
|
19
|
+
* delimiter: string,
|
|
20
|
+
* }) -> DiskHashTableClient
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
class DiskHashTableClient {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
this.serverUrl = options.serverUrl
|
|
26
|
+
this.tableName = options.tableName
|
|
27
|
+
this.delimiter = options.delimiter ?? ""
|
|
28
|
+
this.http = new HTTP(this.serverUrl)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @name clear
|
|
33
|
+
*
|
|
34
|
+
* @docs
|
|
35
|
+
* ```specscript
|
|
36
|
+
* module DiskHashTable "https://presidium.services/docs/DiskHashTable"
|
|
37
|
+
*
|
|
38
|
+
* clear DiskHashTable.clear
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
async clear() {
|
|
42
|
+
const response = await this.http.POST(`/${this.tableName}/clear`, {
|
|
43
|
+
headers: {
|
|
44
|
+
"Client-Name": "DiskHashTableClient",
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
return handleServerResponse(response)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @name set
|
|
52
|
+
*
|
|
53
|
+
* @docs
|
|
54
|
+
* ```specscript
|
|
55
|
+
* module DiskHashTable "https://presidium.services/docs/DiskHashTable"
|
|
56
|
+
*
|
|
57
|
+
* set DiskHashTable.set
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
async set(key, value) {
|
|
61
|
+
const response = await this.http.POST(`/${this.tableName}/set`, {
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
"Client-Name": "DiskHashTableClient",
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({ key, value }),
|
|
67
|
+
})
|
|
68
|
+
await handleServerResponse(response)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @name get
|
|
73
|
+
*
|
|
74
|
+
* @docs
|
|
75
|
+
* ```specscript
|
|
76
|
+
* module DiskHashTable "https://presidium.services/docs/DiskHashTable"
|
|
77
|
+
*
|
|
78
|
+
* get DiskHashTable.get
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
async get(key) {
|
|
82
|
+
const response = await this.http.POST(`/${this.tableName}/get`, {
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
"Client-Name": "DiskHashTableClient",
|
|
86
|
+
},
|
|
87
|
+
body: JSON.stringify({ key }),
|
|
88
|
+
})
|
|
89
|
+
if (response.status == 499) {
|
|
90
|
+
return undefined
|
|
91
|
+
}
|
|
92
|
+
return handleServerResponse(response)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @name getBinary
|
|
97
|
+
*
|
|
98
|
+
* @docs
|
|
99
|
+
* ```specscript
|
|
100
|
+
* module DiskHashTable "https://presidium.services/docs/DiskHashTable"
|
|
101
|
+
*
|
|
102
|
+
* getBinary DiskHashTable.getBinary
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
async getBinary(key) {
|
|
106
|
+
const response = await this.http.POST(`/${this.tableName}/getBinary`, {
|
|
107
|
+
headers: {
|
|
108
|
+
"Content-Type": "application/json",
|
|
109
|
+
"Client-Name": "DiskHashTableClient",
|
|
110
|
+
},
|
|
111
|
+
body: JSON.stringify({ key }),
|
|
112
|
+
})
|
|
113
|
+
return handleServerResponse(response)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @name delete
|
|
118
|
+
*
|
|
119
|
+
* @docs
|
|
120
|
+
* ```specscript
|
|
121
|
+
* module DiskHashTable "https://presidium.services/docs/DiskHashTable"
|
|
122
|
+
*
|
|
123
|
+
* delete DiskHashTable.delete
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
async delete(key) {
|
|
127
|
+
const response = await this.http.POST(`/${this.tableName}/delete`, {
|
|
128
|
+
headers: {
|
|
129
|
+
"Content-Type": "application/json",
|
|
130
|
+
"Client-Name": "DiskHashTableClient",
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify({ key }),
|
|
133
|
+
})
|
|
134
|
+
const didDeleteText = await handleServerResponse(response)
|
|
135
|
+
return didDeleteText == "true"
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @name count
|
|
140
|
+
*
|
|
141
|
+
* @docs
|
|
142
|
+
* ```specscript
|
|
143
|
+
* count() -> Promise<number>
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
async count() {
|
|
147
|
+
const response = await this.http.POST(`/${this.tableName}/count`, {
|
|
148
|
+
headers: {
|
|
149
|
+
"Client-Name": "DiskHashTableClient",
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
const scount = await handleServerResponse(response)
|
|
153
|
+
return Number(scount)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @name iterator
|
|
158
|
+
*
|
|
159
|
+
* @docs
|
|
160
|
+
* ```specscript
|
|
161
|
+
* iterator(options {
|
|
162
|
+
* valueType: "string"|"binary",
|
|
163
|
+
* }) -> values AsyncIterator<string|Buffer>
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
async iterator(options = {}) {
|
|
167
|
+
const { valueType } = options
|
|
168
|
+
const response = await this.http.POST(`/${this.tableName}/iterator`, {
|
|
169
|
+
headers: {
|
|
170
|
+
"Content-Type": "application/json",
|
|
171
|
+
"Client-Name": "DiskHashTableClient",
|
|
172
|
+
},
|
|
173
|
+
body: JSON.stringify(options),
|
|
174
|
+
})
|
|
175
|
+
if (valueType == "binary") {
|
|
176
|
+
return handleServerResponse(response, {
|
|
177
|
+
binaryStream: true,
|
|
178
|
+
delimiter: this.delimiter,
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
return handleServerResponse(response, {
|
|
182
|
+
textStream: true,
|
|
183
|
+
delimiter: this.delimiter,
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @name entriesIterator
|
|
189
|
+
*
|
|
190
|
+
* @docs
|
|
191
|
+
* ```specscript
|
|
192
|
+
* entriesIterator(options {
|
|
193
|
+
* valueType: 'string'|'binary',
|
|
194
|
+
* }) -> entries AsyncIterator<[key string, value string|Buffer]>
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
async entriesIterator(options = {}) {
|
|
198
|
+
const { valueType } = options
|
|
199
|
+
const response = await this.http.POST(`/${this.tableName}/entriesIterator`, {
|
|
200
|
+
headers: {
|
|
201
|
+
"Content-Type": "application/json",
|
|
202
|
+
"Client-Name": "DiskHashTableClient",
|
|
203
|
+
},
|
|
204
|
+
body: JSON.stringify({ valueType }),
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
if (valueType == "binary") {
|
|
208
|
+
const iter = await handleServerResponse(response, {
|
|
209
|
+
binaryEntriesStream: true,
|
|
210
|
+
delimiter: this.delimiter,
|
|
211
|
+
entryLength: 2,
|
|
212
|
+
})
|
|
213
|
+
return map(iter, curry.arity(4, buffersToEntry, __, 2, "utf8", valueType))
|
|
214
|
+
}
|
|
215
|
+
const iter = await handleServerResponse(response, {
|
|
216
|
+
textEntriesStream: true,
|
|
217
|
+
delimiter: this.delimiter,
|
|
218
|
+
entryLength: 2,
|
|
219
|
+
})
|
|
220
|
+
return map(iter, curry.arity(4, buffersToEntry, __, 2, "utf8", valueType))
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
module.exports = DiskHashTableClient
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presidium DB Client and Server may be freely distributed under the CFOSS license.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
require("rubico/global")
|
|
6
|
+
const HTTP = require("presidium/HTTP")
|
|
7
|
+
const handleServerResponse = require("./handleServerResponse")
|
|
8
|
+
const buffersToEntry = require("./buffersToEntry")
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @name DiskSortedHashTableClient
|
|
12
|
+
*
|
|
13
|
+
* @docs
|
|
14
|
+
* ```specscript
|
|
15
|
+
* new DiskSortedHashTableClient(options {
|
|
16
|
+
* serverUrl: string,
|
|
17
|
+
* tableName: string,
|
|
18
|
+
* sortValueType: "string"|"number",
|
|
19
|
+
* degree: number,
|
|
20
|
+
* delimiter: string,
|
|
21
|
+
* }) -> DiskSortedHashTableClient
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
class DiskSortedHashTableClient {
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.serverUrl = options.serverUrl
|
|
27
|
+
this.tableName = options.tableName
|
|
28
|
+
this.sortValueType = options.sortValueType
|
|
29
|
+
this.degree = options.degree ?? 2
|
|
30
|
+
this.delimiter = options.delimiter ?? ""
|
|
31
|
+
this.http = new HTTP(this.serverUrl)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @name clear
|
|
36
|
+
*
|
|
37
|
+
* @docs
|
|
38
|
+
* ```specscript
|
|
39
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
40
|
+
*
|
|
41
|
+
* clear DiskSortedHashTable.clear
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
async clear() {
|
|
45
|
+
const response = await this.http.POST(`/${this.tableName}/clear`, {
|
|
46
|
+
headers: {
|
|
47
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
48
|
+
"Sort-Value-Type": this.sortValueType,
|
|
49
|
+
"Degree": Number(this.degree),
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
return handleServerResponse(response)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @name set
|
|
57
|
+
*
|
|
58
|
+
* @docs
|
|
59
|
+
* ```specscript
|
|
60
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
61
|
+
*
|
|
62
|
+
* set DiskSortedHashTable.set
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
async set(key, value, sortValue) {
|
|
66
|
+
const response = await this.http.POST(`/${this.tableName}/set`, {
|
|
67
|
+
headers: {
|
|
68
|
+
"Content-Type": "application/json",
|
|
69
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
70
|
+
"Sort-Value-Type": this.sortValueType,
|
|
71
|
+
"Degree": Number(this.degree),
|
|
72
|
+
},
|
|
73
|
+
body: JSON.stringify({ key, value, sortValue }),
|
|
74
|
+
})
|
|
75
|
+
await handleServerResponse(response)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @name get
|
|
80
|
+
*
|
|
81
|
+
* @docs
|
|
82
|
+
* ```specscript
|
|
83
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
84
|
+
*
|
|
85
|
+
* get DiskSortedHashTable.get
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async get(key) {
|
|
89
|
+
const response = await this.http.POST(`/${this.tableName}/get`, {
|
|
90
|
+
headers: {
|
|
91
|
+
"Content-Type": "application/json",
|
|
92
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
93
|
+
"Sort-Value-Type": this.sortValueType,
|
|
94
|
+
"Degree": Number(this.degree),
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify({ key }),
|
|
97
|
+
})
|
|
98
|
+
if (response.status == 499) {
|
|
99
|
+
return undefined
|
|
100
|
+
}
|
|
101
|
+
return handleServerResponse(response)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @name getBinary
|
|
106
|
+
*
|
|
107
|
+
* @docs
|
|
108
|
+
* ```specscript
|
|
109
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
110
|
+
*
|
|
111
|
+
* getBinary DiskSortedHashTable.getBinary
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
async getBinary(key) {
|
|
115
|
+
const response = await this.http.POST(`/${this.tableName}/getBinary`, {
|
|
116
|
+
headers: {
|
|
117
|
+
"Content-Type": "application/json",
|
|
118
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
119
|
+
"Sort-Value-Type": this.sortValueType,
|
|
120
|
+
"Degree": Number(this.degree),
|
|
121
|
+
},
|
|
122
|
+
body: JSON.stringify({ key }),
|
|
123
|
+
})
|
|
124
|
+
return handleServerResponse(response)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @name forwardIterator
|
|
129
|
+
*
|
|
130
|
+
* @docs
|
|
131
|
+
* ```specscript
|
|
132
|
+
* forwardIterator(options {
|
|
133
|
+
* exclusiveStartKey: string,
|
|
134
|
+
* startingSortValue: string|number,
|
|
135
|
+
* endingSortValue: string|number,
|
|
136
|
+
* valueType: 'string'|'binary',
|
|
137
|
+
* }) -> values AsyncIterator<string|Buffer>
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
async forwardIterator(options = {}) {
|
|
141
|
+
const { valueType } = options
|
|
142
|
+
const response = await this.http.POST(`/${this.tableName}/forwardIterator`, {
|
|
143
|
+
headers: {
|
|
144
|
+
"Content-Type": "application/json",
|
|
145
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
146
|
+
"Sort-Value-Type": this.sortValueType,
|
|
147
|
+
"Degree": Number(this.degree),
|
|
148
|
+
},
|
|
149
|
+
body: JSON.stringify(options),
|
|
150
|
+
})
|
|
151
|
+
if (valueType == "binary") {
|
|
152
|
+
return handleServerResponse(response, {
|
|
153
|
+
binaryStream: true,
|
|
154
|
+
delimiter: this.delimiter,
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
return handleServerResponse(response, {
|
|
158
|
+
textStream: true,
|
|
159
|
+
delimiter: this.delimiter,
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @name reverseIterator
|
|
165
|
+
*
|
|
166
|
+
* @docs
|
|
167
|
+
* ```specscript
|
|
168
|
+
* reverseIterator(options {
|
|
169
|
+
* exclusiveStartKey: string,
|
|
170
|
+
* startingSortValue: string|number,
|
|
171
|
+
* endingSortValue: string|number,
|
|
172
|
+
* valueType: 'string'|'binary',
|
|
173
|
+
* }) -> values AsyncIterator<string|Buffer>
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
async reverseIterator(options = {}) {
|
|
177
|
+
const { valueType } = options
|
|
178
|
+
const response = await this.http.POST(`/${this.tableName}/reverseIterator`, {
|
|
179
|
+
headers: {
|
|
180
|
+
"Content-Type": "application/json",
|
|
181
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
182
|
+
"Sort-Value-Type": this.sortValueType,
|
|
183
|
+
"Degree": Number(this.degree),
|
|
184
|
+
},
|
|
185
|
+
body: JSON.stringify(options),
|
|
186
|
+
})
|
|
187
|
+
if (valueType == "binary") {
|
|
188
|
+
return handleServerResponse(response, {
|
|
189
|
+
binaryStream: true,
|
|
190
|
+
delimiter: this.delimiter,
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
return handleServerResponse(response, {
|
|
194
|
+
textStream: true,
|
|
195
|
+
delimiter: this.delimiter,
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @name forwardEntriesIterator
|
|
201
|
+
*
|
|
202
|
+
* @docs
|
|
203
|
+
* ```specscript
|
|
204
|
+
* forwardEntriesIterator(options {
|
|
205
|
+
* exclusiveStartKey: string,
|
|
206
|
+
* startingSortValue: string|number,
|
|
207
|
+
* endingSortValue: string|number,
|
|
208
|
+
* valueType: 'string'|'binary',
|
|
209
|
+
* }) -> values AsyncIterator<string|Buffer>
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
async forwardEntriesIterator(options = {}) {
|
|
213
|
+
const { valueType } = options
|
|
214
|
+
const response = await this.http.POST(`/${this.tableName}/forwardEntriesIterator`, {
|
|
215
|
+
headers: {
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
218
|
+
"Sort-Value-Type": this.sortValueType,
|
|
219
|
+
"Degree": Number(this.degree),
|
|
220
|
+
},
|
|
221
|
+
body: JSON.stringify(options),
|
|
222
|
+
})
|
|
223
|
+
if (valueType == "binary") {
|
|
224
|
+
const iter = await handleServerResponse(response, {
|
|
225
|
+
binaryEntriesStream: true,
|
|
226
|
+
delimiter: this.delimiter,
|
|
227
|
+
entryLength: 3,
|
|
228
|
+
})
|
|
229
|
+
return map(iter, curry(buffersToEntry, __, 3, "utf8", valueType, this.sortValueType))
|
|
230
|
+
}
|
|
231
|
+
const iter = await handleServerResponse(response, {
|
|
232
|
+
textEntriesStream: true,
|
|
233
|
+
delimiter: this.delimiter,
|
|
234
|
+
entryLength: 3,
|
|
235
|
+
})
|
|
236
|
+
return map(iter, curry(buffersToEntry, __, 3, "utf8", valueType, this.sortValueType))
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @name reverseEntriesIterator
|
|
241
|
+
*
|
|
242
|
+
* @docs
|
|
243
|
+
* ```specscript
|
|
244
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
245
|
+
*
|
|
246
|
+
* reverseEntriesIterator DiskSortedHashTable.reverseEntriesIterator
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
async reverseEntriesIterator(options = {}) {
|
|
250
|
+
const { valueType } = options
|
|
251
|
+
const response = await this.http.POST(`/${this.tableName}/reverseEntriesIterator`, {
|
|
252
|
+
headers: {
|
|
253
|
+
"Content-Type": "application/json",
|
|
254
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
255
|
+
"Sort-Value-Type": this.sortValueType,
|
|
256
|
+
"Degree": Number(this.degree),
|
|
257
|
+
},
|
|
258
|
+
body: JSON.stringify(options),
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
if (valueType == "binary") {
|
|
262
|
+
const iter = await handleServerResponse(response, {
|
|
263
|
+
binaryEntriesStream: true,
|
|
264
|
+
delimiter: this.delimiter,
|
|
265
|
+
entryLength: 3,
|
|
266
|
+
})
|
|
267
|
+
return map(iter, curry(buffersToEntry, __, 3, "utf8", valueType, this.sortValueType))
|
|
268
|
+
}
|
|
269
|
+
const iter = await handleServerResponse(response, {
|
|
270
|
+
textEntriesStream: true,
|
|
271
|
+
delimiter: this.delimiter,
|
|
272
|
+
entryLength: 3,
|
|
273
|
+
})
|
|
274
|
+
return map(iter, curry(buffersToEntry, __, 3, "utf8", valueType, this.sortValueType))
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* @name delete
|
|
279
|
+
*
|
|
280
|
+
* @docs
|
|
281
|
+
* ```specscript
|
|
282
|
+
* module DiskSortedHashTable "https://presidium.services/docs/DiskSortedHashTable"
|
|
283
|
+
*
|
|
284
|
+
* delete DiskSortedHashTable.delete
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
async delete(key) {
|
|
288
|
+
const response = await this.http.POST(`/${this.tableName}/delete`, {
|
|
289
|
+
headers: {
|
|
290
|
+
"Content-Type": "application/json",
|
|
291
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
292
|
+
"Sort-Value-Type": this.sortValueType,
|
|
293
|
+
"Degree": Number(this.degree),
|
|
294
|
+
},
|
|
295
|
+
body: JSON.stringify({ key }),
|
|
296
|
+
})
|
|
297
|
+
const didDeleteText = await handleServerResponse(response)
|
|
298
|
+
return didDeleteText == "true"
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @name count
|
|
303
|
+
*
|
|
304
|
+
* @docs
|
|
305
|
+
* ```specscript
|
|
306
|
+
* count() -> Promise<number>
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
async count() {
|
|
310
|
+
const response = await this.http.POST(`/${this.tableName}/count`, {
|
|
311
|
+
headers: {
|
|
312
|
+
"Client-Name": "DiskSortedHashTableClient",
|
|
313
|
+
"Sort-Value-Type": this.sortValueType,
|
|
314
|
+
"Degree": Number(this.degree),
|
|
315
|
+
},
|
|
316
|
+
})
|
|
317
|
+
return Number(await handleServerResponse(response))
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
module.exports = DiskSortedHashTableClient
|
package/README.md
CHANGED
|
@@ -1,3 +1,55 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Presidium DB Client and Server
|
|
2
|
+

|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
Source code: [GitHub](https://github.com/richytong/presidium-websocket) |
|
|
5
|
+
License: [CFOSS](https://cloutsworld.com/en-us/legal/license/cfoss)
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
[](https://codecov.io/gh/richytong/presidium-db-client-server)
|
|
9
|
+
[](https://www.npmjs.com/package/presidium-db-client-server)
|
|
10
|
+
|
|
11
|
+
Presidium DB Client and Server.
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const DatabaseServer = require("presidium-db-client-server/DatabaseServer")
|
|
15
|
+
const DiskHashTableClient = require("presidium-db-client-server/DiskHashTableClient")
|
|
16
|
+
|
|
17
|
+
const server = new DatabaseServer({
|
|
18
|
+
databasePath: `${__dirname}/database`,
|
|
19
|
+
})
|
|
20
|
+
await server.init()
|
|
21
|
+
|
|
22
|
+
server.listen(5000, () => {
|
|
23
|
+
console.log("Database server listening on port 5000")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const sessionHt = new DiskHashTableClient({
|
|
27
|
+
serverUrl: "http://localhost:7357",
|
|
28
|
+
tableName: "Session",
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const accessToken = "token"
|
|
32
|
+
const session = { accessToken }
|
|
33
|
+
|
|
34
|
+
await sessionHt.set(accessToken, JSON.stringify(session))
|
|
35
|
+
|
|
36
|
+
const sessionJson = await sessionHt.get(accessToken)
|
|
37
|
+
|
|
38
|
+
await sessionHt.delete(accessToken)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Docs
|
|
42
|
+
Coming soon.
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
with [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm):
|
|
47
|
+
```bash
|
|
48
|
+
npm i presidium-db-client-server
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
Presidium DB Client and Server is distributed under the [CFOSS License](https://cloutsworld.com/en-us/legal/license/cfoss).
|
|
53
|
+
|
|
54
|
+
## Support
|
|
55
|
+
* minimum Node.js version: 16
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presidium DB Client and Server may be freely distributed under the CFOSS license.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const EventEmitter = require("events")
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @name TextEntriesStream
|
|
9
|
+
*
|
|
10
|
+
* @docs
|
|
11
|
+
* ```coffeescript [specscript]
|
|
12
|
+
* module EventEmitter "./specscript/EventEmitter.ss"
|
|
13
|
+
*
|
|
14
|
+
* TextEntriesStream(
|
|
15
|
+
* readable stream.Readable,
|
|
16
|
+
* entryLength number,
|
|
17
|
+
* delimiter string
|
|
18
|
+
* ) -> textEntriesStream EventEmitter
|
|
19
|
+
*
|
|
20
|
+
* textEntriesStream.on("entry", (entry Array<string>, keyEncoding string) -> ())
|
|
21
|
+
*
|
|
22
|
+
* textEntriesStream.on("end", () -> ())
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
class TextEntriesStream extends EventEmitter {
|
|
26
|
+
constructor(readable, entryLength, delimiter, encoding) {
|
|
27
|
+
super()
|
|
28
|
+
|
|
29
|
+
delimiter ??= ""
|
|
30
|
+
encoding ??= "utf8"
|
|
31
|
+
|
|
32
|
+
let s = ""
|
|
33
|
+
let entry = []
|
|
34
|
+
readable.on('data', (chunk, encoding) => {
|
|
35
|
+
if (typeof chunk == 'string') {
|
|
36
|
+
s += Buffer.from(chunk, encoding).toString(encoding)
|
|
37
|
+
} else {
|
|
38
|
+
s += chunk.toString(encoding)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let delimiterIndex = s.indexOf(delimiter)
|
|
42
|
+
while (delimiterIndex > -1) {
|
|
43
|
+
const text = s.slice(0, delimiterIndex)
|
|
44
|
+
entry.push(text)
|
|
45
|
+
if (entry.length == entryLength) {
|
|
46
|
+
this.emit("entry", entry, encoding)
|
|
47
|
+
entry = []
|
|
48
|
+
}
|
|
49
|
+
s = s.slice(delimiterIndex + 1)
|
|
50
|
+
delimiterIndex = s.indexOf(delimiter)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
readable.on("end", () => {
|
|
55
|
+
if (s.length > 0) {
|
|
56
|
+
entry.push(s)
|
|
57
|
+
}
|
|
58
|
+
if (entry.length == entryLength) {
|
|
59
|
+
this.emit("entry", entry, encoding)
|
|
60
|
+
this.emit("end")
|
|
61
|
+
entry = []
|
|
62
|
+
} else if (entry.length > 0) {
|
|
63
|
+
const error = new Error("last entry")
|
|
64
|
+
error.entry = entry
|
|
65
|
+
this.emit("error", error)
|
|
66
|
+
} else {
|
|
67
|
+
this.emit("end")
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = TextEntriesStream
|