joplin-notes/Export-9fad9947-5bd5-4195-952b-6512c5a4beb1/Web development 83dd4e6675f04ba782a6865a434a0598/NodeJS 6d499253059041d699e2e6fa36ded013.md
2026-11-04 00:33:23 +05:30

21 KiB

NodeJS

NodeGUI

  • Extract metadata

    https://www.npmjs.com/package/metadata-scraper?activeTab=readme

    https://www.npmjs.com/package/page-metadata-parser

    https://www.scrapingbee.com/blog/node-fetch/

  • Page scrapper

    browser as service : https://www.browserless.io/blog/2022/05/31/youtube-scraper/

    https://www.demo2s.com/node.js/node-js-url-project-playlist-scraper-takes-a-youtube-playlist-url-gi.html

    • for lazy loading content(which render when we scroll down to that):

      https://stackoverflow.com/questions/51529332/puppeteer-scroll-down-until-you-cant-anymore

      const puppeteer = require('puppeteer');
      
      (async () => {
          const browser = await puppeteer.launch({
              headless: false
          });
          const page = await browser.newPage();
          await page.goto('https://www.yoursite.com');
          await page.setViewport({
              width: 1200,
              height: 800
          });
      
          await autoScroll(page);
      
          await page.screenshot({
              path: 'yoursite.png',
              fullPage: true
          });
      
          await browser.close();
      })();
      
      async function autoScroll(page){
          await page.evaluate(async () => {
              await new Promise((resolve) => {
                  var totalHeight = 0;
                  var distance = 100;
                  var timer = setInterval(() => {
                      var scrollHeight = document.body.scrollHeight;
                      window.scrollBy(0, distance);
                      totalHeight += distance;
      								// scrollheight is subtracted as innerheight is portion
      								// only rendered so remaining portion to be scrolled down
                      if(totalHeight >= scrollHeight - window.innerHeight){
                          clearInterval(timer);
                          resolve();
                      }
                  }, 100);
              });
          });
      }
      
  • Download any file from web server

    https://www.npmjs.com/package/nodejs-file-downloader

  • Alternative of axios

    https://stackoverflow.com/questions/13864983/how-to-post-multipart-form-data-with-node-js-superagent

    const superagent = require('superagent');
    superagent
      .post('https://www.y2mate.com/mates/en423/analyze/ajax')
      // .send(formData) // sends a JSON post body
      .set('accept', 'application/json')
      .field('url',url)
      .field('q_auto',0)
      .field('ajax',2)
    
      .end(async (err, res) => {
    		// same as finally means both then and catch
    	}
    

    or for json:

    superagent
      .post('/api/pet')
      .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
      .set('X-API-Key', 'foobar')
      .set('accept', 'json')
      .end((err, res) => {
        // Calling the end function will send the request
      });
    
    // promise with then/catch
    superagent.post('/api/pet').then(console.log).catch(console.error);
    
  • Inspect nodejs app to Chrome

    node inspect app.js

    In browser type

    chrome://inspect and open dedicated DevTools for Node

  • Update nodejs and npm

    https://www.geeksforgeeks.org/how-to-update-node-js-and-npm-to-next-version/

  • Taking input in synchronous way

    // to take input from user
    const readlineSync = require('readline-sync');
    
    	// Wait for user's response.
    	const phrase = readlineSync.question('Type a phrase (or quit to exit program): ');
    
    
  • async fs without callback hell

    https://www.youtube.com/watch?v=msnTtrx2C4s

  • file system cache in nodejs

    https://www.npmjs.com/package/file-system-cache

    Example:

    // const NodeCache=require('node-cache')
    // const myCache=new NodeCache();
    const FileSystemCache_1 =require('file-system-cache')
    
    const options={basePath: "./.cache", // Optional. Path where cache files are stored (default).
      ns: "my-namespace" // Optional. A grouping namespace for items.
    }
    const cache=new FileSystemCache_1.FileSystemCache(options)
    
    const heavyComputation=()=>{
    	 let temp = 0;
         for(let i=0; i<100000; i++)
              temp = (Math.random()*5342)%i;
         return 123;
    }
    
    const main=async()=>{
    	if(await cache.fileExists('key'))
    	{
    		console.log('res: ',await cache.get('key'))
    	}
    	else{
    		let res= heavyComputation()
    		cache.set('key',res)
    		console.log('Value not present performing calculation')
    
    		console.log('res2: ',res)
    	}
    
    }
    main()
    

    some changes in ./node_modules/file-system-cache/lib/index.js :

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.FileSystemCache = void 0;
    const FileSystemCache_1 = require("./FileSystemCache");
    Object.defineProperty(exports, "FileSystemCache", { enumerable: true, get: function () { return FileSystemCache_1.FileSystemCache; } });
    const Cache= (options) => new FileSystemCache_1.FileSystemCache(options);
    exports.default = FileSystemCache_1
    
  • Mockable.io

    used by front end developers to create rest api

  • read only file system

    When working on read only file system use the /tmp to perform write functions.

    fs.writeFileSync("/tmp/users.json", JSON.stringify(users))

  • state management in nodejs

    //state.js file
    
    class State { 
        constructor() { 
            this.currentState = false; 
    		this.data = null;
            this.setState = (st) => { 
                this.currentState=st;
            }; 
    		this.setData = (da) => {
    			this.data = da;
    		}
        } 
    }
    
    const appState = new State(); 
    module.exports = appState;
    
    const appState = require("./state");
    const PORT = 3000;
    
    const promiseSetTimeOut = (time) => {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve();
        }, time);
      });
    };
    
    const app = express();
    
    app.use(express.static(__dirname + "/public"));
    
    app.get("/getData", (req, res) => {
      res.json(appState.currentState);
    });
    
    app.put("/updateData/:st", (req, res) => {
      const { st } = req.params;
      let stBool = false;
    		let actualValue;
      if (st == "1") {
        stBool = true;
    	actualValue=st
      }
    
      res.json("updating");
      const promiseID = promiseSetTimeOut(5000);
      promiseID.then(() => {
        // console.log("updated ",stBool);
        appState.setState(stBool);
    	appState.setData(actualValue);
        console.log(appState);
      });
    });
    
    app.listen(PORT, () => {
      console.log("listening");
    });
    
  • Polling for limited timeout problem

    https://www.npmjs.com/package/http-delayed-response

    https://spin.atomicobject.com/2018/05/15/extending-heroku-timeout-node/

  • Deta

    https://deta.space/docs/en/quickstart-guides/node https://deta.space/docs/en/build/quick-starts/node https://deta.space/builder : to go to builder page Uninstalling deta: It makes a hidden directory named as ".detaspace" in home directory just delete it .

    to open setting: https://deta.space/?tty_open=settings

  • Installing from github instead of npm library

    "ytdl-core": "git+https://github.com/khlevon/node-ytdl-core.git#v4.11.4-patch.2”

    npm -i [https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2](https://github.com/khlevon/node-ytdl-core#v4.11.4-patch.2) —no-audit

  • Socket

    backend

    const WebSocket = require("ws");
    
    // creating a websocket connection at port 8080
    const server = new WebSocket.Server({ port: 8080 });
    
    // this callback function will respond once client connect to ws://localhost:8080
    server.on("connection", (socket) => {
      console.log("connected");
    
      // this one respond once client send back a message here
      socket.on("message", (message, isString) => {
        // by default message is in buffer si convert it to string
        let msg = isString ? message : message.toString();
        console.log("message: ", msg);
    
        // sending back the same message which was sent here by client
        socket.send(msg);
      });
    });
    

    frontend

    // ws protocol is used instead of http
    const socket = new WebSocket("ws://localhost:8080");
    
    // this callback function will respond once server send back a message here
    socket.onmessage = (e) => {
      console.log("Message: ", e.data);
    };
    
    document.querySelector("button").onclick = () => {
      // send method to send the message to server
      socket.send("helo");
    };
    
    • socket.io

      high level library which uses ws to provide support for multiple clients and broadcasting

      backend

      const PORT = process.env.PORT || 8080;
      
      const httpServer = require("http").createServer();
      const socketIO = require("socket.io");
      
      // linking with httpserver 
      const io = socketIO(httpServer, {
        cors: { origin: "*" },
      });
      
      // when client connects to the server
      io.on("connection", (socket) => {
        console.log(`user connected ${socket.id}`);
      
        // when listening to custom event named 'message'
        socket.on("message", (message) => {
      
          // here using socket.boradcast.emit will send message to all client except the one who originally sent to server
          socket.broadcast.emit(
            "message",
            `${socket.id.substr(0, 2)} said ${message}`
          );
      
          // to send to all including OP, use io.emit
          // and for particular client use
          // io.to(socket.id). emit("event", data);
      
        });
      });
      
      httpServer.listen(PORT, () => {
        console.log("listening");
      });
      

      frontend

      const socket = io("ws://localhost:8080");
      
      const list = document.querySelector("#msgList");
      const inputEle = document.querySelector("#chatInput");
      
      // when listening to custom event named 'message'
      socket.on("message", (msg) => {
        const li = document.createElement("li");
        li.innerText = msg;
        list.appendChild(li);
      });
      
      document.querySelector("#sendBtn").onclick = () => {
        const text = inputEle.value;
      
        // emitting custom event named 'message' and passing the paramter $text
        socket.emit("message", text);
        const li = document.createElement("li");
        li.innerText = `you said ${text}`;
        list.appendChild(li);
        inputEle.value = "";
      };
      
  • AES file encryption

    https://github.com/AKASHAorg/easy-web-crypto

    function processFile(evt) {
        var file = evt.target.files[0],
            reader = new FileReader();
    
        reader.onload = function(e) {
            var data = e.target.result,
                iv = crypto.getRandomValues(new Uint8Array(16));
    
            crypto.subtle.generateKey({ 'name': 'AES-CBC', 'length': 256 }, false, ['encrypt', 'decrypt'])
                .then(key => crypto.subtle.encrypt({ 'name': 'AES-CBC', iv }, key, data) )
                .then(encrypted => {
                    console.log(encrypted);
                    alert('The encrypted data is ' + encrypted.byteLength + ' bytes long'); // encrypted is an ArrayBuffer
                })
                .catch(console.error);
        }
    
        reader.readAsArrayBuffer(file);
    

    <input type="file" id="file-upload" onchange="processFile(event)">

    • more

      https://stackoverflow.com/questions/60520526/aes-encryption-and-decryption-of-files-using-crypto-js

      Slicing files to chunks

      https://stackoverflow.com/questions/29731329/cryptojs-sha256-large-file-progressive-checksum/62824083#62824083

      function encrypt(input) {
          var file = input.files[0];
          var reader = new FileReader();
          reader.onload = () => {
              var key = "1234567887654321";
              var wordArray = CryptoJS.lib.WordArray.create(reader.result);           // Convert: ArrayBuffer -> WordArray
              var encrypted = CryptoJS.AES.encrypt(wordArray, key).toString();        // Encryption: I: WordArray -> O: -> Base64 encoded string (OpenSSL-format)
      
              var fileEnc = new Blob([encrypted]);                                    // Create blob from string
      
              var a = document.createElement("a");
              var url = window.URL.createObjectURL(fileEnc);
              var filename = file.name + ".enc";
              a.href = url;
              a.download = filename;
              a.click();
              window.URL.revokeObjectURL(url);
          };
          reader.readAsArrayBuffer(file);
      }
      
      function convertWordArrayToUint8Array(wordArray) {
          var arrayOfWords = wordArray.hasOwnProperty("words") ? wordArray.words : [];
          var length = wordArray.hasOwnProperty("sigBytes") ? wordArray.sigBytes : arrayOfWords.length * 4;
          var uInt8Array = new Uint8Array(length), index=0, word, i;
          for (i=0; i<length; i++) {
              word = arrayOfWords[i];
              uInt8Array[index++] = word >> 24;
              uInt8Array[index++] = (word >> 16) & 0xff;
              uInt8Array[index++] = (word >> 8) & 0xff;
              uInt8Array[index++] = word & 0xff;
          }
          return uInt8Array;
      }
      
      function decrypt(input) {
          var file = input.files[0];
          var reader = new FileReader();
          reader.onload = () => {
              var key = "1234567887654321";  
      
              var decrypted = CryptoJS.AES.decrypt(reader.result, key);               // Decryption: I: Base64 encoded string (OpenSSL-format) -> O: WordArray
              var typedArray = convertWordArrayToUint8Array(decrypted);               // Convert: WordArray -> typed array
      
              var fileDec = new Blob([typedArray]);                                   // Create blob from typed array
      
              var a = document.createElement("a");
              var url = window.URL.createObjectURL(fileDec);
              var filename = file.name.substr(0, file.name.length - 4) + ".dec";
              a.href = url;
              a.download = filename;
              a.click();
              window.URL.revokeObjectURL(url);
          };
          reader.readAsText(file);
      }
      

      Slicing

      import CryptoJS from 'crypto-js';
      
      class ChecksumService {
      
        async sha256(file: File): Promise<string> {
          let sha256 = CryptoJS.algo.SHA256.create();
          const sliceSize = 10_485_760; // 10 MiB
          let start = 0;
      
          while (start < file.size) {
            const slice: Uint8Array = await this.readSlice(file, start, sliceSize);
            const wordArray = CryptoJS.lib.WordArray.create(slice);
            sha256 = sha256.update(wordArray);
            start += sliceSize;
          }
      
          sha256.finalize();
      
          return sha256._hash.toString();
        }
      
        private async readSlice(file: File, start: number, size: number): Promise<Uint8Array> {
          return new Promise<Uint8Array>((resolve, reject) => {
            const fileReader = new FileReader();
            const slice = file.slice(start, start + size);
      
            fileReader.onload = () => resolve(new Uint8Array(fileReader.result as any));
            fileReader.onerror = reject;
            fileReader.readAsArrayBuffer(slice);
          });
        }
      
      }
      
  • Tauri

    Download first_tauri.zip-423.8 MB

    Download linux_tauri.zip-574.9 MB