npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-folder-sync

v1.0.2

Published

Sync folders across network using express js

Downloads

3

Readme

EXPRESS-FOLDER-SYNC

This package allow you to synchronize folders across remote servers (master and slaves). This package exports two express js routers FolderSyncRouterMaster and FolderSyncRouterSlave containing necessary logic to perform sync tasks.

Sync task is optimized so that an heavy media already synced over the network wont be sent again optimizing time and network bandwidth.

Caluculation of the difference of contents is made leveraging hashing techniques in order to detect updates. (Hash map tree reprepresentation of synced folders diffing is done before compressing a zip archive containing the actual ressource to be sent over the network).

see express-folder-sync on npmjs

How does it works

Folders are being synced over two subsequent HTTP calls performed from the slave endpoint (sync) to master API.

1- ask the difference of content SLAVE (syncedDirPath) vs MASTER (syncedDirPath) 2- using the response of the first call (upsertTree and deleteTree objects) ask for the updated and new data (binary data) and place it into the syncedDirPath folder using the upsertTree and delete old data using the deleteTree

Trees are builded using the hash of the files in order to optimize the HTTP calls and data usage.

Warning

The sync operation is not automatically triggered or based on a timer. You have to perform an initial HTTP call to the SLAVE syncRoute endpoint in order to trigger an update.

Quick start

Install the package in your project

npm i express-folder-sync

Master server (source of truth)

All options used in the constructor are default options so you do not have to change any of them nor pass it in the constructor. In order to use the default options you must ensure that :

  • syncedDirPath is a valid path
const express = require("express");
const { FolderSyncRouterMaster } = require("express-folder-sync/build/master");
const app = express();
app.use(express.json());
app.use("/api", new FolderSyncRouterMaster(
    diffRoute = { // name of the route retrieving the content diff on the master server vs slave server
       name: "diff",
       middlewares: [], // extra middlewares can be used to perform logic before calling the endpoint (logging ? )
    },
    filesRoute = { // name of the route sending zip archive containing updated and new files on the master server vs slave server
      name: "files",
      middlewares: [], // extra middlewares can be used to perform logic before calling the endpoint  (logging ? )
    },
    statusRoute = {  // name of the route sending master server status and performing a check of configuration between slave and master
       name: "status",
       middlewares: [], // extra middlewares can be used to perform logic before calling the endpoint (logging ? )
    },
    syncedDirPath = join(cwd(), "public") // directory to be synced (source of truth - the content of this directory will be copied to the slave(s) syncedDirPath dirtectorie(s)) 
));

app.listen(9000, 'localhost', () =>
  console.log(
    `master running at http://localhost:9000`
  )
);

Slave

All options used in the constructor are default options so you do not have to change any of them nor pass it in the constructor. In order to use the default options you must ensure that :

  • syncedDirPath is a valid path
  • tempDirPath is a valid path
  • masterServerOptions.baseURL is valid
const express = require("express");
const { FolderSyncRouterSlave } = require("express-folder-sync/build/slave");
const app = express();
app.use(express.json());
app.use(
  "/api",
  new FolderSyncRouterSlave(
    masterServerOptions = {  // options related to the master server
      baseURL: "http://localhost:9000", // root url of the master server instance
      httpRequestTimeout: 5000, // request timeout (axios is used underneath to perform http calls from the slave router to the master router and ask for data)
      httpRequestHeaders: {}, // extra headers to be used when making http calls to the master server instance 
      routerPrefix: "api", // prefix of the router aka app.use(prefix, FolderSyncRouterMaster)
      diffRoute: { // name of the route retrieving the content diff on the master server vs slave server
        name: "diff",
      },
      filesRoute: { // name of the route sending zip archive containing updated and new files on the master server vs slave server
        name: "files",
      },
      statusRoute: { // name of the route sending master server status and performing a check of configuration between slave and master
        name: "status",
      },
      check: true, // allowing initial request to satus endpoint to be disabled (request is performed at server runtime could be disabled in production environement for example)
    },
   syncedDirPath = join(cwd(), "public"), // path to the folder being synchronized on the slave
   tempDirPath = join(cwd(), "temp"), // path to a temporary directory to store zip files before merging them into the synchronized directory on the slave
   syncRoute = { // endpoint name on the slave (to be called to trigger the syncronization process)
     name: "sync",
     middlewares: [], // extra middlewares can be used to perform logic before calling the endpoint (logging ? )
    },
   forwardedHeadersKeysMap = { // headers keys to be forwarded from the original request when performing http calls to the master api 
      Authorization: true, // allowing for example to pass an authorization headers content for authentication/authorization purposes
    },
   cleanTempDir = true // cleaning temp directory after having merged the content to the syncronized folder
  )
);

app.listen(3000, 'localhost', () =>
  console.log(
    `slave running at http://localhost:3000`
  )
);
// slave's sync endpoint sample success response
{
  "statusCode": 200,
  "datetimeMs": 1661066907603, // Date.now()
  "message": "synced with success",
}

Dependencies