-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http-server with data-structures is developed.
- Loading branch information
1 parent
c5297f3
commit 5a07d0f
Showing
10 changed files
with
273 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Stack & LinkedList http-server implementation. | ||
## Run server | ||
`node server.js` creates server on `localhost:3000` | ||
## Stack | ||
1. Push: `POST /stack`\ | ||
Accepts JSON: `{ "add": <int> or <str> }` | ||
1. Pop: `DELETE /stack`\ | ||
Removes item from the top and return its value. | ||
|
||
## LinkedList | ||
|
||
1. Show list: `GET /linked-list`\ | ||
Shows current LinkedList values. | ||
1. Insert/Remove: `PATCH /linked-list`\ | ||
Accepts JSON: `{ "add": <int> or <str>, "successor": <int> or <str>, "remove": <int> or <str> }`\ | ||
Inserts `'add'` before each `'successor'` if provided, appends to list's head otherwise.\ | ||
Removes `'remove'` values. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const readBody = req => | ||
new Promise(resolve => { | ||
const chunks = []; | ||
|
||
req.on('data', chunk => { | ||
chunks.push(chunk); | ||
}); | ||
|
||
req.on('end', () => { | ||
resolve(Buffer.concat(chunks)); | ||
}); | ||
}); | ||
|
||
const parseJson = async req => readBody(req).then(JSON.parse); | ||
|
||
const validValueCondition = value => | ||
Number.isFinite(value) || typeof value === 'string'; | ||
|
||
const parsedBodyValues = req => | ||
parseJson(req).then(body => | ||
Object.keys(body).reduce((acc, key) => { | ||
if (['add', 'successor', 'remove'].includes(key)) { | ||
if (!validValueCondition(body[key])) | ||
throw SyntaxError( | ||
`'${body[key]}' should be of type 'string' or 'number'.` | ||
); | ||
return { ...acc, [key]: body[key] }; | ||
} | ||
return acc; | ||
}, {}) | ||
); | ||
|
||
module.exports = parsedBodyValues; |
38 changes: 38 additions & 0 deletions
38
submissions/assmass13/data-structures/routers/linked-list-router.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const LinkedList = require('../structures/linked-list'); | ||
const parsedBodyValues = require('../request-handler'); | ||
|
||
class LinkedListRouter { | ||
constructor() { | ||
this.linkedList = new LinkedList(); | ||
this.routes = { | ||
'GET /linked-list': this.getLinkedListRoute.bind(this), | ||
'PATCH /linked-list': this.patchLinkedListRoute.bind(this) | ||
}; | ||
} | ||
|
||
getLinkedListRoute(req, res) { | ||
res.statusCode = 200; | ||
res.end(this.linkedList.showList().toString()); | ||
} | ||
|
||
patchLinkedListRoute(req, res) { | ||
return parsedBodyValues(req, res) | ||
.then(({ add, successor, remove }) => { | ||
if (add && successor) { | ||
this.linkedList.insertBeforeSuccessors(add, successor); | ||
} else if (add) { | ||
this.linkedList.unshift(add); | ||
} else if (remove) { | ||
this.linkedList.removeValue(remove); | ||
} | ||
res.statusCode = 200; | ||
res.end(this.linkedList.showList().toString()); | ||
}) | ||
.catch(error => { | ||
res.statusCode = 400; | ||
res.end(error.toString()); | ||
}); | ||
} | ||
} | ||
|
||
module.exports = LinkedListRouter; |
38 changes: 38 additions & 0 deletions
38
submissions/assmass13/data-structures/routers/stack-router.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const Stack = require('../structures/stack'); | ||
const parsedBodyValues = require('../request-handler'); | ||
|
||
class StackRouter { | ||
constructor() { | ||
this.stack = new Stack(); | ||
this.routes = { | ||
'POST /stack': this.postStackRoute.bind(this), | ||
'DELETE /stack': this.deleteStackRoute.bind(this) | ||
}; | ||
} | ||
|
||
async postStackRoute(req, res) { | ||
return parsedBodyValues(req) | ||
.then(({ add }) => { | ||
this.stack.push(add); | ||
res.statusCode = 201; | ||
res.end(this.stack.showStack().toString()); | ||
}) | ||
.catch(error => { | ||
res.statusCode = 400; | ||
res.end(error.toString()); | ||
}); | ||
} | ||
|
||
deleteStackRoute(req, res) { | ||
const removedNode = this.stack.pop(); | ||
if (removedNode) { | ||
res.statusCode = 200; | ||
res.end(removedNode.value.toString()); | ||
} else { | ||
res.statusCode = 404; | ||
res.end('Stack is empty.'); | ||
} | ||
} | ||
} | ||
|
||
module.exports = StackRouter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const http = require('http'); | ||
|
||
const StackRouter = require('./routers/stack-router'); | ||
const LinkedListRouter = require('./routers/linked-list-router'); | ||
|
||
const routes = { | ||
...new StackRouter().routes, | ||
...new LinkedListRouter().routes | ||
}; | ||
|
||
const noRouteFound = (req, res) => { | ||
res.statusCode = 404; | ||
res.end('Requested resource not found.'); | ||
}; | ||
|
||
const server = http.createServer((req, res) => { | ||
const route = `${req.method} ${req.url}`; | ||
const handler = routes[route] || noRouteFound; | ||
handler(req, res); | ||
}); | ||
|
||
server.listen(3000); |
100 changes: 100 additions & 0 deletions
100
submissions/assmass13/data-structures/structures/linked-list.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
const Node = require('./node'); | ||
|
||
module.exports = class LinkedList { | ||
constructor() { | ||
this.head = null; | ||
this.tail = null; | ||
this.length = 0; | ||
} | ||
|
||
pop() { | ||
if (!this.head) return null; | ||
let currentNode = this.head; | ||
let newTail = currentNode; | ||
while (currentNode.next) { | ||
newTail = currentNode; | ||
currentNode = currentNode.next; | ||
} | ||
this.tail = newTail; | ||
this.tail.next = null; | ||
this.length -= 1; | ||
if (this.length === 0) { | ||
this.head = null; | ||
this.tail = null; | ||
} | ||
return currentNode; | ||
} | ||
|
||
shift() { | ||
if (!this.head) return null; | ||
const oldHead = this.head; | ||
this.head = oldHead.next; | ||
this.length -= 1; | ||
if (this.length === 0) { | ||
this.tail = null; | ||
} | ||
return oldHead; | ||
} | ||
|
||
unshift(value) { | ||
const newNode = new Node(value); | ||
if (!this.head) { | ||
this.head = newNode; | ||
this.tail = newNode; | ||
} else { | ||
newNode.next = this.head; | ||
this.head = newNode; | ||
} | ||
this.length += 1; | ||
return this; | ||
} | ||
|
||
insertBeforeSuccessors(value, successor) { | ||
let previousNode = null; | ||
let currentNode = this.head; | ||
|
||
while (currentNode) { | ||
if (currentNode.value === successor) { | ||
const newNode = new Node(value); | ||
if (previousNode) previousNode.next = newNode; | ||
else this.head = newNode; | ||
newNode.next = currentNode; | ||
} | ||
|
||
previousNode = currentNode; | ||
currentNode = currentNode.next; | ||
} | ||
} | ||
|
||
removeValue(removeValue) { | ||
let previousNode = null; | ||
let currentNode = this.head; | ||
|
||
while (currentNode) { | ||
if (currentNode.value === removeValue) { | ||
if (previousNode) { | ||
currentNode = currentNode.next; | ||
previousNode.next = currentNode; | ||
} else { | ||
this.head = currentNode.next; | ||
currentNode = this.head; | ||
} | ||
} | ||
|
||
while (currentNode && currentNode.value !== removeValue) { | ||
previousNode = currentNode; | ||
currentNode = currentNode.next; | ||
} | ||
} | ||
} | ||
|
||
showList() { | ||
const values = []; | ||
let currentNode = this.head; | ||
while (currentNode) { | ||
values.push(currentNode.value); | ||
currentNode = currentNode.next; | ||
} | ||
return values; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = class Node { | ||
constructor(value) { | ||
this.value = value; | ||
this.next = null; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
const LinkedList = require('./linked-list'); | ||
|
||
module.exports = class Stack { | ||
constructor() { | ||
this.linkedList = new LinkedList(); | ||
} | ||
|
||
push(value) { | ||
return this.linkedList.unshift(value); | ||
} | ||
|
||
pop() { | ||
return this.linkedList.shift(); | ||
} | ||
|
||
showStack() { | ||
return this.linkedList.showList().reverse(); | ||
} | ||
}; |