presidium-db-client-server 0.4.0 → 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,186 +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.path == "/health") {
115
- response.writeHead(200, {
116
- "Content-Type": "text/plain",
117
- })
118
- response.end("OK")
119
- } else if (request.pathDepth == 2) {
120
- const tableName = request.pathSegments[0]
121
- const fname = request.pathSegments[1]
122
- const ht = hts.get(tableName)
123
- ?? 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)
124
117
 
125
- await switchCase(
126
- fname,
118
+ await switchCase(
119
+ fname,
127
120
 
128
- eq("clear"), async () => {
129
- await ht.clear()
130
- response.writeHead(200, {
131
- "Content-Type": "text/plain",
132
- })
133
- response.end("OK")
134
- },
121
+ eq("clear"), async () => {
122
+ await ht.clear()
123
+ response.writeHead(200, {
124
+ "Content-Type": "text/plain",
125
+ })
126
+ response.end("OK")
127
+ },
135
128
 
136
- eq("set"), async () => {
137
- const { key, value, sortValue } = await Readable.JSON(request)
138
- await ht.set(key, value, sortValue)
139
- 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, {
140
143
  "Content-Type": "text/plain",
141
144
  })
142
- response.end("OK")
143
- },
144
-
145
- eq("get"), async () => {
146
- const { key } = await Readable.JSON(request)
147
- const value = await ht.get(key)
148
- if (value === undefined) {
149
- response.writeHead(499, {
150
- "Content-Type": "text/plain",
151
- })
152
- response.end("Resource Not Found")
153
- } else {
154
- response.writeHead(200, {
155
- "Content-Type": "text/plain",
156
- })
157
- response.end(value)
158
- }
159
- },
160
-
161
- eq("getBinary"), async () => {
162
- const { key } = await Readable.JSON(request)
163
- const value = await ht.getBinary(key)
145
+ response.end("Resource Not Found")
146
+ } else {
164
147
  response.writeHead(200, {
165
- "Content-Type": "application/octet-stream",
148
+ "Content-Type": "text/plain",
166
149
  })
167
150
  response.end(value)
168
- },
151
+ }
152
+ },
169
153
 
170
- eq("delete"), async () => {
171
- const { key } = await Readable.JSON(request)
172
- const didDelete = await ht.delete(key)
173
- response.writeHead(200, {
174
- "Content-Type": "text/plain",
175
- })
176
- response.end(String(didDelete))
177
- },
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
+ },
178
162
 
179
- eq("count"), async () => {
180
- const count = ht.count()
181
- response.writeHead(200, {
182
- "Content-Type": "text/plain",
183
- })
184
- response.end(String(count))
185
- },
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
+ },
186
171
 
187
- eq("iterator"), async () => {
188
- const options = await Readable.JSON(request)
189
- response.writeHead(200, {
190
- "Content-Type": "application/octet-stream",
191
- "Content-Encoding": "utf8",
192
- })
193
- const count = ht.count()
194
- for await (const value of ht.iterator(options)) {
195
- response.write(value)
196
- response.write("")
197
- }
198
- response.end()
199
- },
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
+ },
200
179
 
201
- eq("entriesIterator"), async () => {
202
- const options = await Readable.JSON(request)
203
- response.writeHead(200, {
204
- "Content-Type": "application/octet-stream",
205
- "Content-Encoding": "utf8",
206
- })
207
- const count = ht.count()
208
- for await (const [key, value] of ht.entriesIterator(options)) {
209
- response.write(key)
210
- response.write("")
211
- response.write(value)
212
- response.write("")
213
- }
214
- response.end()
215
- },
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
+ },
216
193
 
217
- eq("forwardIterator"), async () => {
218
- const options = await Readable.JSON(request)
219
- response.writeHead(200, {
220
- "Content-Type": "application/octet-stream",
221
- "Content-Encoding": "utf8",
222
- })
223
- const count = ht.count()
224
- for await (const value of ht.forwardIterator(options)) {
225
- response.write(value)
226
- response.write("")
227
- }
228
- response.end()
229
- },
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
+ },
230
209
 
231
- eq("reverseIterator"), async () => {
232
- const options = await Readable.JSON(request)
233
- response.writeHead(200, {
234
- "Content-Type": "application/octet-stream",
235
- "Content-Encoding": "utf8",
236
- })
237
- const count = ht.count()
238
- for await (const value of ht.reverseIterator(options)) {
239
- response.write(value)
240
- response.write("")
241
- }
242
- response.end()
243
- },
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
+ },
244
223
 
245
- eq("forwardEntriesIterator"), async () => {
246
- const options = await Readable.JSON(request)
247
- response.writeHead(200, {
248
- "Content-Type": "application/octet-stream",
249
- "Content-Encoding": "utf8",
250
- })
251
- const count = ht.count()
252
- for await (const [key, value, sortValue] of ht.forwardEntriesIterator(options)) {
253
- response.write(key)
254
- response.write("")
255
- response.write(value)
256
- response.write("")
257
- response.write(String(sortValue))
258
- response.write("")
259
- }
260
- response.end()
261
- },
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
+ },
262
237
 
263
- eq("reverseEntriesIterator"), async () => {
264
- const options = await Readable.JSON(request)
265
- response.writeHead(200, {
266
- "Content-Type": "application/octet-stream",
267
- "Content-Encoding": "utf8",
268
- })
269
- const count = ht.count()
270
- for await (const [key, value, sortValue] of ht.reverseEntriesIterator(options)) {
271
- response.write(key)
272
- response.write("")
273
- response.write(value)
274
- response.write("")
275
- response.write(String(sortValue))
276
- response.write("")
277
- }
278
- response.end()
279
- },
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
+ },
280
255
 
281
- async () => {
282
- const error = new Error("Forbidden: Hash Table Method")
283
- error.code = "403"
284
- throw error
285
- },
286
- )
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
+ )
287
280
 
288
- } else {
289
- response.writeHead(404, {
290
- "Content-Type": "text/plain",
291
- })
292
- response.end("Not Found")
293
- }
294
281
  }
295
282
  }
296
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.4.0",
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",