@einaraglen/quorum 1.0.3 → 1.0.4

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
@@ -16,7 +16,7 @@ When a pod starts up it runs an election: it contacts every peer with a higher n
16
16
 
17
17
  ### Transport — the wire
18
18
 
19
- All coordination travels over a single internal HTTP port (default `4001`). Each pod runs a small Express server on that port with five endpoints:
19
+ All coordination travels over a single internal HTTP port (default `4001`). Each pod runs a small tinyhttp server on that port with five endpoints:
20
20
 
21
21
  | Route | Purpose |
22
22
  | ---------------------------- | --------------------------------------------- |
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,qBAAa,SAAS;IACpB,SAAgB,OAAO,EAAE,OAAO,KAAK,CAAC;IACtC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,CAAS;IAExB,YAAY,IAAI,GAAE,gBAAqB,EAMtC;IAEY,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAYnF;IAEY,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASpD;IAEM,KAAK,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI,CA4CzC;IAEM,IAAI,IAAI,IAAI,CAElB;CACF"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAQF,qBAAa,SAAS;IACpB,SAAgB,OAAO,EAAE,OAAO,KAAK,CAAC;IACtC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,CAA4B;IAE3C,YAAY,IAAI,GAAE,gBAAqB,EAMtC;IAEY,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAYnF;IAEY,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASpD;IAEM,KAAK,CAAC,EAAE,EAAE,kBAAkB,GAAG,IAAI,CA8CzC;IAEM,IAAI,IAAI,IAAI,CAElB;CACF"}
@@ -1,4 +1,10 @@
1
- import express from "express";
1
+ import { App } from "@tinyhttp/app";
2
+ const readJsonBody = async (req) => {
3
+ const chunks = [];
4
+ for await (const chunk of req)
5
+ chunks.push(chunk);
6
+ return chunks.length === 0 ? {} : JSON.parse(Buffer.concat(chunks).toString("utf8"));
7
+ };
2
8
  export class Transport {
3
9
  fetchFn;
4
10
  port;
@@ -39,23 +45,23 @@ export class Transport {
39
45
  }
40
46
  }
41
47
  start(cb) {
42
- const app = express();
43
- app.use(express.json());
44
- app.get("/health", (_, res) => {
48
+ const app = new App();
49
+ const onJsonMessage = (handle) => async (req, res) => {
50
+ try {
51
+ handle(await readJsonBody(req));
52
+ res.sendStatus(200);
53
+ }
54
+ catch (err) {
55
+ this.logger.error(err);
56
+ res.status(500).json({ status: "ERROR", error: err?.message ?? String(err) });
57
+ }
58
+ };
59
+ app.get("/health", (_req, res) => {
45
60
  res.json({ status: "OK", timestamp: new Date().toISOString() });
46
61
  });
47
- app.post("/bully/election", (req, res) => {
48
- cb.onElectionMessage(req.body?.id);
49
- res.sendStatus(200);
50
- });
51
- app.post("/bully/coordinator", (req, res) => {
52
- cb.onCoordinatorMessage(req.body?.id);
53
- res.sendStatus(200);
54
- });
55
- app.post("/bully/message", (req, res) => {
56
- cb.onMessage(req.body?.event, req.body?.payload);
57
- res.sendStatus(200);
58
- });
62
+ app.post("/bully/election", onJsonMessage((body) => cb.onElectionMessage(body?.id)));
63
+ app.post("/bully/coordinator", onJsonMessage((body) => cb.onCoordinatorMessage(body?.id)));
64
+ app.post("/bully/message", onJsonMessage((body) => cb.onMessage(body?.event, body?.payload)));
59
65
  app.get("/channel/stream/:event", (req, res) => {
60
66
  const eventName = req.params.event;
61
67
  res.writeHead(200, {
@@ -67,13 +73,9 @@ export class Transport {
67
73
  cb.channel.on(eventName, forward);
68
74
  req.on("close", () => cb.channel.off(eventName, forward));
69
75
  });
70
- app.use((err, _req, res, _next) => {
71
- this.logger.error(err);
72
- res.status(500).json({ status: "ERROR", error: err?.message ?? String(err) });
73
- });
74
76
  const onListening = () => this.logger.info(`Internal coordination server listening on port ${this.port}`);
75
77
  this.server = this.internalHost
76
- ? app.listen(this.port, this.internalHost, onListening)
78
+ ? app.listen(this.port, onListening, this.internalHost)
77
79
  : app.listen(this.port, onListening);
78
80
  }
79
81
  stop() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@einaraglen/quorum",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Distributed pod coordination: Bully leader election and work sharding",
5
5
  "keywords": [
6
6
  "leader-election",
@@ -36,7 +36,6 @@
36
36
  "check": "npm run format:check && npm run lint"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/express": "^5.0.6",
40
39
  "@types/node": "^24.9.2",
41
40
  "oxlint": "^1.80.0",
42
41
  "prettier": "^3.9.6",
@@ -44,6 +43,6 @@
44
43
  "typescript": "^7.0.2"
45
44
  },
46
45
  "dependencies": {
47
- "express": "^5.2.1"
46
+ "@tinyhttp/app": "^3.0.11"
48
47
  }
49
48
  }