Comparing version 1.0.0 to 2.0.0
@@ -1,27 +0,64 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Writer = void 0; | ||
const fs_1 = __importDefault(require("fs")); | ||
const path_1 = __importDefault(require("path")); | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
// Returns a temporary file | ||
// Example: for /some/file will return /some/.file.tmp | ||
function getTempFilename(file) { | ||
return path_1.default.join(path_1.default.dirname(file), '.' + path_1.default.basename(file) + '.tmp'); | ||
return path.join(path.dirname(file), '.' + path.basename(file) + '.tmp'); | ||
} | ||
class Writer { | ||
export class Writer { | ||
constructor(filename) { | ||
this.locked = false; | ||
this.prev = null; | ||
this.next = null; | ||
this.nextPromise = null; | ||
this.nextData = null; | ||
Object.defineProperty(this, "filename", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "tempFilename", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: void 0 | ||
}); | ||
Object.defineProperty(this, "locked", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: false | ||
}); | ||
Object.defineProperty(this, "prev", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: null | ||
}); | ||
Object.defineProperty(this, "next", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: null | ||
}); | ||
Object.defineProperty(this, "nextPromise", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: null | ||
}); | ||
Object.defineProperty(this, "nextData", { | ||
enumerable: true, | ||
configurable: true, | ||
writable: true, | ||
value: null | ||
}); | ||
this.filename = filename; | ||
this.tempFilename = getTempFilename(filename); | ||
} | ||
// File is locked, add data for later | ||
_add(data) { | ||
// Only keep most recent data | ||
this.nextData = data; | ||
// Create a singleton promise to resolve all next promises once next data is written | ||
this.nextPromise || (this.nextPromise = new Promise((resolve, reject) => { | ||
this.next = [resolve, reject]; | ||
})); | ||
// Return a promise that will resolve at the same time as next promise | ||
return new Promise((resolve, reject) => { | ||
@@ -32,11 +69,16 @@ var _a; | ||
} | ||
// File isn't locked, write data | ||
async _write(data) { | ||
var _a, _b; | ||
// Lock file | ||
this.locked = true; | ||
try { | ||
await fs_1.default.promises.writeFile(this.tempFilename, data, 'utf-8'); | ||
await fs_1.default.promises.rename(this.tempFilename, this.filename); | ||
// Atomic write | ||
await fs.promises.writeFile(this.tempFilename, data, 'utf-8'); | ||
await fs.promises.rename(this.tempFilename, this.filename); | ||
// Call resolve | ||
(_a = this.prev) === null || _a === void 0 ? void 0 : _a[0](); | ||
} | ||
catch (err) { | ||
// Call reject | ||
(_b = this.prev) === null || _b === void 0 ? void 0 : _b[1](err); | ||
@@ -46,2 +88,3 @@ throw err; | ||
finally { | ||
// Unlock file | ||
this.locked = false; | ||
@@ -61,2 +104,1 @@ this.prev = this.next; | ||
} | ||
exports.Writer = Writer; |
{ | ||
"name": "steno", | ||
"version": "1.0.0", | ||
"description": "Fast file writer with race condition prevention and atomic writing", | ||
"main": "lib/index.js", | ||
"version": "2.0.0", | ||
"description": "Specialized fast async file writer", | ||
"type": "module", | ||
"exports": "./lib/index.js", | ||
"types": "lib/index.d.ts", | ||
@@ -12,8 +13,10 @@ "files": [ | ||
"scripts": { | ||
"test": "jest", | ||
"test": "npm run build && xv 'lib/**/*.test.js'", | ||
"build": "del-cli lib && tsc", | ||
"lint": "eslint src --ext .ts --ignore-path .gitignore", | ||
"prepare": "husky install", | ||
"prepublishOnly": "npm run build", | ||
"postversion": "git push && git push --tags && npm publish", | ||
"benchmark": "ts-node src/benchmark.ts" | ||
"benchmark": "npm run build && node lib/benchmark.js", | ||
"commit": "commit" | ||
}, | ||
@@ -47,22 +50,13 @@ "repository": { | ||
"@commitlint/prompt-cli": "^12.0.1", | ||
"@tsconfig/node10": "^1.0.7", | ||
"@types/jest": "^26.0.20", | ||
"@types/node": "^14.14.31", | ||
"@sindresorhus/tsconfig": "^1.0.2", | ||
"@types/node": "^15.6.1", | ||
"@typicode/eslint-config": "^0.1.0", | ||
"del-cli": "^3.0.1", | ||
"husky": "^5.1.3", | ||
"jest": "^26.6.3", | ||
"prettier": "^2.2.1", | ||
"ts-jest": "^26.5.3", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.2" | ||
"husky": "^6.0.0", | ||
"typescript": "^4.2.2", | ||
"xv": "^0.1.0" | ||
}, | ||
"eslintConfig": { | ||
"extends": "@typicode", | ||
"parserOptions": { | ||
"project": [ | ||
"./tsconfig.lint.json" | ||
] | ||
} | ||
"engines": { | ||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# steno [![](http://img.shields.io/npm/dm/steno.svg?style=flat)](https://www.npmjs.org/package/steno) [![Node.js CI](https://github.com/typicode/steno/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/steno/actions/workflows/node.js.yml) | ||
# Steno [![](http://img.shields.io/npm/dm/steno.svg?style=flat)](https://www.npmjs.org/package/steno) [![Node.js CI](https://github.com/typicode/steno/actions/workflows/node.js.yml/badge.svg)](https://github.com/typicode/steno/actions/workflows/node.js.yml) | ||
@@ -13,4 +13,4 @@ > Specialized fast async file writer | ||
- Fast | ||
- Lightweight | ||
- Fast (see benchmark) | ||
- Lightweight (~6kb) | ||
- Promise-based | ||
@@ -37,12 +37,19 @@ - Atomic write | ||
`npm run benchmark` | ||
`npm run benchmark` (see `src/benchmark.ts`) | ||
``` | ||
Write 1KB data to the same file x 1000 | ||
fs : 68.464ms | ||
steno: 0.578ms | ||
fs : 62.303ms | ||
steno : 1.384ms | ||
fs.txt = steno.txt ✓ | ||
Write 1MB data to the same file x 1000 | ||
fs : 2.166s | ||
steno: 1.153ms | ||
fs : 2.300s | ||
steno : 5.444ms | ||
fs.txt = steno.txt ✓ | ||
``` | ||
@@ -49,0 +56,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
7342
10
114
58
Yes