presidium-db-client-server 0.3.1 → 0.5.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.
@@ -111,181 +111,173 @@ function DatabaseHandler(options) {
111
111
  request.pathSegments = request.path.slice(1).split("/")
112
112
  request.pathDepth = request.pathSegments.length
113
113
 
114
- if (request.pathDepth == 2) {
115
- const tableName = request.pathSegments[0]
116
- const fname = request.pathSegments[1]
117
- const ht = hts.get(tableName)
118
- ?? await getHt(tableName, request, manifestHt)
114
+ const tableName = request.pathSegments[0]
115
+ const fname = request.pathSegments[1]
116
+ const ht = hts.get(tableName) ?? await getHt(tableName, request, manifestHt)
119
117
 
120
- await switchCase(
121
- fname,
118
+ await switchCase(
119
+ fname,
122
120
 
123
- eq("clear"), async () => {
124
- await ht.clear()
125
- response.writeHead(200, {
126
- "Content-Type": "text/plain",
127
- })
128
- response.end("OK")
129
- },
121
+ eq("clear"), async () => {
122
+ await ht.clear()
123
+ response.writeHead(200, {
124
+ "Content-Type": "text/plain",
125
+ })
126
+ response.end("OK")
127
+ },
130
128
 
131
- eq("set"), async () => {
132
- const { key, value, sortValue } = await Readable.JSON(request)
133
- await ht.set(key, value, sortValue)
134
- response.writeHead(200, {
129
+ eq("set"), async () => {
130
+ const { key, value, sortValue } = await Readable.JSON(request)
131
+ await ht.set(key, value, sortValue)
132
+ response.writeHead(200, {
133
+ "Content-Type": "text/plain",
134
+ })
135
+ response.end("OK")
136
+ },
137
+
138
+ eq("get"), async () => {
139
+ const { key } = await Readable.JSON(request)
140
+ const value = await ht.get(key)
141
+ if (value === undefined) {
142
+ response.writeHead(499, {
135
143
  "Content-Type": "text/plain",
136
144
  })
137
- response.end("OK")
138
- },
139
-
140
- eq("get"), async () => {
141
- const { key } = await Readable.JSON(request)
142
- const value = await ht.get(key)
143
- if (value === undefined) {
144
- response.writeHead(499, {
145
- "Content-Type": "text/plain",
146
- })
147
- response.end("Resource Not Found")
148
- } else {
149
- response.writeHead(200, {
150
- "Content-Type": "text/plain",
151
- })
152
- response.end(value)
153
- }
154
- },
155
-
156
- eq("getBinary"), async () => {
157
- const { key } = await Readable.JSON(request)
158
- const value = await ht.getBinary(key)
145
+ response.end("Resource Not Found")
146
+ } else {
159
147
  response.writeHead(200, {
160
- "Content-Type": "application/octet-stream",
148
+ "Content-Type": "text/plain",
161
149
  })
162
150
  response.end(value)
163
- },
151
+ }
152
+ },
164
153
 
165
- eq("delete"), async () => {
166
- const { key } = await Readable.JSON(request)
167
- const didDelete = await ht.delete(key)
168
- response.writeHead(200, {
169
- "Content-Type": "text/plain",
170
- })
171
- response.end(String(didDelete))
172
- },
154
+ eq("getBinary"), async () => {
155
+ const { key } = await Readable.JSON(request)
156
+ const value = await ht.getBinary(key)
157
+ response.writeHead(200, {
158
+ "Content-Type": "application/octet-stream",
159
+ })
160
+ response.end(value)
161
+ },
173
162
 
174
- eq("count"), async () => {
175
- const count = ht.count()
176
- response.writeHead(200, {
177
- "Content-Type": "text/plain",
178
- })
179
- response.end(String(count))
180
- },
163
+ eq("delete"), async () => {
164
+ const { key } = await Readable.JSON(request)
165
+ const didDelete = await ht.delete(key)
166
+ response.writeHead(200, {
167
+ "Content-Type": "text/plain",
168
+ })
169
+ response.end(String(didDelete))
170
+ },
181
171
 
182
- eq("iterator"), async () => {
183
- const options = await Readable.JSON(request)
184
- response.writeHead(200, {
185
- "Content-Type": "application/octet-stream",
186
- "Content-Encoding": "utf8",
187
- })
188
- const count = ht.count()
189
- for await (const value of ht.iterator(options)) {
190
- response.write(value)
191
- response.write("")
192
- }
193
- response.end()
194
- },
172
+ eq("count"), async () => {
173
+ const count = ht.count()
174
+ response.writeHead(200, {
175
+ "Content-Type": "text/plain",
176
+ })
177
+ response.end(String(count))
178
+ },
195
179
 
196
- eq("entriesIterator"), async () => {
197
- const options = await Readable.JSON(request)
198
- response.writeHead(200, {
199
- "Content-Type": "application/octet-stream",
200
- "Content-Encoding": "utf8",
201
- })
202
- const count = ht.count()
203
- for await (const [key, value] of ht.entriesIterator(options)) {
204
- response.write(key)
205
- response.write("")
206
- response.write(value)
207
- response.write("")
208
- }
209
- response.end()
210
- },
180
+ eq("iterator"), async () => {
181
+ const options = await Readable.JSON(request)
182
+ response.writeHead(200, {
183
+ "Content-Type": "application/octet-stream",
184
+ "Content-Encoding": "utf8",
185
+ })
186
+ const count = ht.count()
187
+ for await (const value of ht.iterator(options)) {
188
+ response.write(value)
189
+ response.write("")
190
+ }
191
+ response.end()
192
+ },
211
193
 
212
- eq("forwardIterator"), async () => {
213
- const options = await Readable.JSON(request)
214
- response.writeHead(200, {
215
- "Content-Type": "application/octet-stream",
216
- "Content-Encoding": "utf8",
217
- })
218
- const count = ht.count()
219
- for await (const value of ht.forwardIterator(options)) {
220
- response.write(value)
221
- response.write("")
222
- }
223
- response.end()
224
- },
194
+ eq("entriesIterator"), async () => {
195
+ const options = await Readable.JSON(request)
196
+ response.writeHead(200, {
197
+ "Content-Type": "application/octet-stream",
198
+ "Content-Encoding": "utf8",
199
+ })
200
+ const count = ht.count()
201
+ for await (const [key, value] of ht.entriesIterator(options)) {
202
+ response.write(key)
203
+ response.write("")
204
+ response.write(value)
205
+ response.write("")
206
+ }
207
+ response.end()
208
+ },
225
209
 
226
- eq("reverseIterator"), async () => {
227
- const options = await Readable.JSON(request)
228
- response.writeHead(200, {
229
- "Content-Type": "application/octet-stream",
230
- "Content-Encoding": "utf8",
231
- })
232
- const count = ht.count()
233
- for await (const value of ht.reverseIterator(options)) {
234
- response.write(value)
235
- response.write("")
236
- }
237
- response.end()
238
- },
210
+ eq("forwardIterator"), async () => {
211
+ const options = await Readable.JSON(request)
212
+ response.writeHead(200, {
213
+ "Content-Type": "application/octet-stream",
214
+ "Content-Encoding": "utf8",
215
+ })
216
+ const count = ht.count()
217
+ for await (const value of ht.forwardIterator(options)) {
218
+ response.write(value)
219
+ response.write("")
220
+ }
221
+ response.end()
222
+ },
239
223
 
240
- eq("forwardEntriesIterator"), async () => {
241
- const options = await Readable.JSON(request)
242
- response.writeHead(200, {
243
- "Content-Type": "application/octet-stream",
244
- "Content-Encoding": "utf8",
245
- })
246
- const count = ht.count()
247
- for await (const [key, value, sortValue] of ht.forwardEntriesIterator(options)) {
248
- response.write(key)
249
- response.write("")
250
- response.write(value)
251
- response.write("")
252
- response.write(String(sortValue))
253
- response.write("")
254
- }
255
- response.end()
256
- },
224
+ eq("reverseIterator"), async () => {
225
+ const options = await Readable.JSON(request)
226
+ response.writeHead(200, {
227
+ "Content-Type": "application/octet-stream",
228
+ "Content-Encoding": "utf8",
229
+ })
230
+ const count = ht.count()
231
+ for await (const value of ht.reverseIterator(options)) {
232
+ response.write(value)
233
+ response.write("")
234
+ }
235
+ response.end()
236
+ },
257
237
 
258
- eq("reverseEntriesIterator"), async () => {
259
- const options = await Readable.JSON(request)
260
- response.writeHead(200, {
261
- "Content-Type": "application/octet-stream",
262
- "Content-Encoding": "utf8",
263
- })
264
- const count = ht.count()
265
- for await (const [key, value, sortValue] of ht.reverseEntriesIterator(options)) {
266
- response.write(key)
267
- response.write("")
268
- response.write(value)
269
- response.write("")
270
- response.write(String(sortValue))
271
- response.write("")
272
- }
273
- response.end()
274
- },
238
+ eq("forwardEntriesIterator"), async () => {
239
+ const options = await Readable.JSON(request)
240
+ response.writeHead(200, {
241
+ "Content-Type": "application/octet-stream",
242
+ "Content-Encoding": "utf8",
243
+ })
244
+ const count = ht.count()
245
+ for await (const [key, value, sortValue] of ht.forwardEntriesIterator(options)) {
246
+ response.write(key)
247
+ response.write("")
248
+ response.write(value)
249
+ response.write("")
250
+ response.write(String(sortValue))
251
+ response.write("")
252
+ }
253
+ response.end()
254
+ },
275
255
 
276
- async () => {
277
- const error = new Error("Forbidden: Hash Table Method")
278
- error.code = "403"
279
- throw error
280
- },
281
- )
256
+ eq("reverseEntriesIterator"), async () => {
257
+ const options = await Readable.JSON(request)
258
+ response.writeHead(200, {
259
+ "Content-Type": "application/octet-stream",
260
+ "Content-Encoding": "utf8",
261
+ })
262
+ const count = ht.count()
263
+ for await (const [key, value, sortValue] of ht.reverseEntriesIterator(options)) {
264
+ response.write(key)
265
+ response.write("")
266
+ response.write(value)
267
+ response.write("")
268
+ response.write(String(sortValue))
269
+ response.write("")
270
+ }
271
+ response.end()
272
+ },
273
+
274
+ async () => {
275
+ const error = new Error("Forbidden: Hash Table Method")
276
+ error.code = "403"
277
+ throw error
278
+ },
279
+ )
282
280
 
283
- } else {
284
- response.writeHead(404, {
285
- "Content-Type": "text/plain",
286
- })
287
- response.end("Not Found")
288
- }
289
281
  }
290
282
  }
291
283
 
package/DatabaseServer.js CHANGED
@@ -7,12 +7,18 @@ const HTTP = require("presidium/HTTP")
7
7
  const DiskHashTable = require("presidium/DiskHashTable")
8
8
  const DiskSortedHashTable = require("presidium/DiskSortedHashTable")
9
9
  const DatabaseHandler = require("./DatabaseHandler")
10
+ const healthCheckHandler = require("./healthCheckHandler")
11
+ const notFoundHandler = require("./notFoundHandler")
10
12
 
11
13
  /**
12
14
  * @name DatabaseServer
13
15
  *
14
16
  * @docs
15
17
  * ```specscript
18
+ * module HTTP "https://presidium.services/docs/HTTP"
19
+ *
20
+ * HTTP.Handler(request HTTP.Request, response HTTP.Response) -> ()
21
+ *
16
22
  * new DatabaseServer(options {
17
23
  * databasePath: string,
18
24
  * manifestTableName: string,
@@ -21,11 +27,11 @@ const DatabaseHandler = require("./DatabaseHandler")
21
27
  * defaultTableInitialLength: number,
22
28
  * defaultTableItemSize: number,
23
29
  * defaultDiskSortedHashTableDegree: number,
24
- * }) -> server DatabaseServer
30
+ * }, ...handlers Arguments<HTTP.Handler>) -> server DatabaseServer
25
31
  * ```
26
32
  */
27
33
  class DatabaseServer {
28
- constructor(options) {
34
+ constructor(options, ...handlers) {
29
35
  this.databasePath = options.databasePath
30
36
  this.manifestTableName = options.manifestTableName ?? "Manifest"
31
37
  this.manifestTableInitialLength = options.manifestTableInitialLength ?? 1048576
@@ -33,6 +39,7 @@ class DatabaseServer {
33
39
  this.defaultTableInitialLength = options.defaultTableInitialLength ?? 1048576
34
40
  this.defaultTableItemSize = options.defaultTableItemSize ?? 1024
35
41
  this.defaultDiskSortedHashTableDegree = options.defaultDiskSortedHashTableDegree ?? 2
42
+ this.handlers = handlers
36
43
  this.server = null
37
44
  this.hts = new Map()
38
45
  }
@@ -67,8 +74,16 @@ class DatabaseServer {
67
74
  hts: this.hts,
68
75
  })
69
76
 
70
- const handler = tryCatch(
71
- databaseHandler,
77
+ const router = tryCatch(
78
+ switchCase(
79
+ request => request.path == "/health",
80
+ healthCheckHandler,
81
+
82
+ request => request.pathDepth == 2,
83
+ databaseHandler,
84
+
85
+ notFoundHandler,
86
+ ),
72
87
  function errorHandler(error, request, response) {
73
88
  response.writeHead(error.code ?? 500, {
74
89
  "Content-Type": "text/plain",
@@ -77,6 +92,21 @@ class DatabaseServer {
77
92
  }
78
93
  )
79
94
 
95
+ const handler = all.series([
96
+ ...this.handlers,
97
+ request => {
98
+ const { pathname } = new URL(`http://*${request.url}`)
99
+ request.path = decodeURIComponent(
100
+ pathname == "/" ? pathname
101
+ : pathname.endsWith("/") ? pathname.slice(0, -1)
102
+ : pathname
103
+ )
104
+ request.pathSegments = request.path.slice(1).split("/")
105
+ request.pathDepth = request.pathSegments.length
106
+ },
107
+ router,
108
+ ])
109
+
80
110
  this.server = HTTP.Server(handler)
81
111
  }
82
112
 
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @name healthCheckHandler
3
+ *
4
+ * @docs
5
+ * ```specscript
6
+ * module HTTP "https://presidium.services/docs/HTTP"
7
+ *
8
+ * healthCheckHandler(request HTTP.Request, response HTTP.Response) -> ()
9
+ * ```
10
+ */
11
+ function healthCheckHandler(request, response) {
12
+ response.writeHead(200, {
13
+ 'Content-Type': 'text/plain',
14
+ })
15
+ response.end('OK')
16
+ }
17
+
18
+ module.exports = healthCheckHandler
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @name notFoundHandler
3
+ *
4
+ * @docs
5
+ * ```specscript
6
+ * module HTTP "https://presidium.services/docs/HTTP"
7
+ *
8
+ * notFoundHandler(request HTTP.Request, response HTTP.Response) -> ()
9
+ * ```
10
+ */
11
+ function notFoundHandler(request, response) {
12
+ response.writeHead(404, {
13
+ "Content-Type": "text/plain",
14
+ })
15
+ response.end("Not Found")
16
+ }
17
+
18
+ module.exports = notFoundHandler
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presidium-db-client-server",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "Presidium DB client and server library",
5
5
  "author": "Richard Tong",
6
6
  "license": "CFOSS",
@@ -21,7 +21,9 @@
21
21
  "TextEntriesStream.js",
22
22
  "TextStream.js",
23
23
  "buffersToEntry.js",
24
- "handleServerResponse.js"
24
+ "handleServerResponse.js",
25
+ "healthCheckHandler.js",
26
+ "notFoundHandler.js"
25
27
  ],
26
28
  "keywords": [
27
29
  "presidium",