A wrapper around fs.writeFile for safely replacing a file, especially to guard against double-writes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
AJ ONeal 54b2954229 provide instruction for old node users 6 years ago
.gitignore Initial commit 9 years ago
LICENSE Initial commit 9 years ago
README.md clarify use of promises 8 years ago
index.js provide instruction for old node users 6 years ago
package.json provide instruction for old node users 6 years ago
test.js add singleton 8 years ago

README.md

safe-replace

A micro-module for safely replacing a file.

This is intended to be generally safe even when a function that writes a file is accidentally called twice (as may happen with node cluster).

Commandline Reference

If I want to safely replace a file with a new version, I would do so like this:

# create the new version
touch keep.txt.RANDOM.tmp

# remove the previous backup
rm -f keep.txt.bak

# move the current version to the backup
mv keep.txt keep.txt.bak

# move the new version to the current
mv keep.txt.RANDOM.tmp keep.txt

If keep.txt became corrupt and I wanted to use the backup, I would do this:

# copy the backup to the new version
rsync keep.txt.bak keep.txt

In Node

I ported that proccess to node.

sfs.writeFileAsync
sfs.stageAsync
sfs.commitAsync
sfs.revertAsync
// default behavior is to concat (filename + '.' + rnd() + '.tmp')
var safeReplace = require('safe-replace').create({ tmp: 'tmp', bak: 'bak' });

var data = new Buffer('A priceless document');
safeReplace.writeFileAsync('keep.txt', data, 'ascii').then(function () {
  fs.readdir('.', function (nodes) {
    console.log('file system nodes', nodes);
    // keep.txt
    // keep.txt.bak
  });
});

// let's say I want to write a tmp file and not commit it... weird
safeReplace.stageAsync('keep.txt', data, 'ascii').then(function (tmpname) {
  fs.readdir('.', function (nodes) {
    console.log('file system nodes', nodes);
    // keep.txt.ac71teh8mja.tmp
  });
});

// let's say I wrote keep.txt.x7t7sq926.tmp with my own mechanism
safeReplace.commitAsync('keep.txt.x7t7sq926.tmp', 'keep.txt').then(function () {
  fs.readdir('.', function (nodes) {
    console.log('file system nodes', nodes);
    // keep.txt
    // keep.txt.bak
  });
});

// let's say I want to revert the file from the '.bak'
safeReplace.revertAsync('keep.txt').then(function () {
  fs.readdir('.', function (nodes) {
    console.log('file system nodes', nodes);
    // keep.txt
    // keep.txt.bak
  });
});