instbyte 1.6.3 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instbyte",
3
- "version": "1.6.3",
3
+ "version": "1.8.0",
4
4
  "description": "A self-hosted LAN sharing utility for fast, frictionless file, link, and snippet exchange across devices — no cloud required.",
5
5
  "main": "server/server.js",
6
6
  "bin": {
package/server/server.js CHANGED
@@ -366,16 +366,47 @@ app.post("/pin/:id", (req, res) => {
366
366
  /* GET ITEMS */
367
367
  app.get("/items/:channel", (req, res) => {
368
368
  const channel = req.params.channel;
369
+ const page = parseInt(req.query.page) || 1;
370
+ const limit = 10;
371
+ const offset = (page - 1) * limit;
369
372
 
370
- db.all(
371
- `SELECT * FROM items WHERE channel=? ORDER BY pinned DESC, created_at DESC`,
373
+ db.get(
374
+ `SELECT COUNT(*) as count FROM items WHERE channel=? AND pinned=0`,
372
375
  [channel],
373
- (err, rows) => {
374
- res.json(rows);
376
+ (err, row) => {
377
+ if (err) return res.status(500).json({ error: "DB error" });
378
+
379
+ const totalUnpinned = row.count;
380
+ const hasMore = offset + limit < totalUnpinned;
381
+
382
+ db.all(
383
+ `SELECT * FROM items WHERE channel=? AND pinned=0
384
+ ORDER BY created_at DESC LIMIT ? OFFSET ?`,
385
+ [channel, limit, offset],
386
+ (err, unpinned) => {
387
+ if (err) return res.status(500).json({ error: "DB error" });
388
+
389
+ if (page === 1) {
390
+ // only fetch pinned on first page
391
+ db.all(
392
+ `SELECT * FROM items WHERE channel=? AND pinned=1
393
+ ORDER BY created_at DESC`,
394
+ [channel],
395
+ (err, pinned) => {
396
+ if (err) return res.status(500).json({ error: "DB error" });
397
+ res.json({ items: [...pinned, ...unpinned], hasMore, page });
398
+ }
399
+ );
400
+ } else {
401
+ res.json({ items: unpinned, hasMore, page });
402
+ }
403
+ }
404
+ );
375
405
  }
376
406
  );
377
407
  });
378
408
 
409
+
379
410
  /* SEARCH */
380
411
  app.get("/search/:channel/:q", (req, res) => {
381
412
  const { channel, q } = req.params;
@@ -624,6 +655,7 @@ let connectedUsers = 0;
624
655
 
625
656
  io.on("connection", (socket) => {
626
657
  connectedUsers++;
658
+ io.emit("user-count", connectedUsers);
627
659
 
628
660
  let username = "Unknown";
629
661
 
@@ -635,6 +667,7 @@ io.on("connection", (socket) => {
635
667
  socket.on("disconnect", () => {
636
668
  connectedUsers--;
637
669
  console.log(username + " disconnected | total:", connectedUsers);
670
+ io.emit("user-count", connectedUsers);
638
671
  });
639
672
  });
640
673
 
@@ -696,3 +729,33 @@ findFreePort(PREFERRED).then(p => {
696
729
  console.log("");
697
730
  });
698
731
  });
732
+
733
+
734
+ // ========================
735
+ // GRACEFUL SHUTDOWN
736
+ // ========================
737
+ function shutdown(signal) {
738
+ console.log(`\n${signal} received — shutting down gracefully...`);
739
+
740
+ // stop accepting new connections
741
+ server.close(() => {
742
+ console.log("HTTP server closed");
743
+
744
+ // close database connection
745
+ db.close((err) => {
746
+ if (err) console.error("Error closing database:", err);
747
+ else console.log("Database connection closed");
748
+ console.log("Shutdown complete");
749
+ process.exit(0);
750
+ });
751
+ });
752
+
753
+ // force exit after 10 seconds if something hangs
754
+ setTimeout(() => {
755
+ console.error("Forced shutdown after timeout");
756
+ process.exit(1);
757
+ }, 10000);
758
+ }
759
+
760
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
761
+ process.on("SIGINT", () => shutdown("SIGINT"));