Comparing version 2.1.1 to 2.2.0
@@ -24,6 +24,6 @@ let events = require(`events`) | ||
this.flushAtEOF = options.flushAtEOF || false; | ||
this.encoding = options.encoding || `utf-8`; | ||
this.encoding = options.encoding || 'utf-8'; | ||
const fromBeginning = options.fromBeginning || false; | ||
this.nLines = options.nLines || undefined; | ||
this.logger.info(`Tail starting...`) | ||
@@ -53,10 +53,20 @@ this.logger.info(`filename: ${this.filename}`); | ||
this.logger.info(`fromBeginning: ${fromBeginning}`); | ||
let startingPos = undefined; | ||
let startingCursor; | ||
if (fromBeginning) { | ||
startingPos = 0; | ||
//if fromBeginning triggers a check for content to flush the existing file | ||
//without waiting for a new appended line | ||
this.change(this.filename); | ||
} | ||
this.watch(startingPos); | ||
startingCursor = 0; | ||
} else if (this.nLines !== undefined) { | ||
const data = fs.readFileSync(this.filename, { | ||
flag: 'r', | ||
encoding:this.encoding | ||
}); | ||
const tokens = data.split(this.separator); | ||
const dropLastToken = (tokens[tokens.length-1] === '') ? 1:0;//if the file end with empty line ignore line NL | ||
const match = data.match(new RegExp(`(?:[^\r\n]*[\r]{0,1}\n){${tokens.length - this.nLines - dropLastToken}}`)); | ||
startingCursor = (match && match.length) ? Buffer.byteLength(match[0], this.encoding) : this.latestPosition(); | ||
} else { | ||
startingCursor = this.latestPosition() ; | ||
} | ||
if (startingCursor === undefined) throw new Error("Tail can't initialize."); | ||
const flush = fromBeginning || (this.nLines != undefined); | ||
this.watch(startingCursor, flush); | ||
} | ||
@@ -109,9 +119,9 @@ | ||
change(filename) { | ||
change() { | ||
let p = this.latestPosition() | ||
if (p < this.pos) {//scenario where text is not appended but it's actually a w+ | ||
this.pos = p | ||
} else if (p > this.pos) { | ||
this.queue.push({ start: this.pos, end: p}); | ||
this.pos = p | ||
if (p < this.currentCursorPos) {//scenario where text is not appended but it's actually a w+ | ||
this.currentCursorPos = p | ||
} else if (p > this.currentCursorPos) { | ||
this.queue.push({ start: this.currentCursorPos, end: p}); | ||
this.currentCursorPos = p | ||
if (this.queue.length == 1) { | ||
@@ -123,6 +133,4 @@ this.internalDispatcher.emit("next"); | ||
watch(startingPos) { | ||
if (this.isWatching) { | ||
return | ||
} | ||
watch(startingCursor, flush) { | ||
if (this.isWatching) return; | ||
this.logger.info(`filesystem.watch present? ${fs.watch != undefined}`); | ||
@@ -132,3 +140,5 @@ this.logger.info(`useWatchFile: ${this.useWatchFile}`); | ||
this.isWatching = true; | ||
this.pos = (startingPos === undefined) ? this.latestPosition() : startingPos; | ||
this.currentCursorPos = startingCursor; | ||
//force a file flush is either fromBegining or nLines flags were passed. | ||
if (flush) this.change(); | ||
@@ -165,3 +175,3 @@ try { | ||
this.rewatchId = setTimeout((() => { | ||
this.watch(this.pos); | ||
this.watch(this.currentCursorPos); | ||
}), 1000); | ||
@@ -179,3 +189,3 @@ } else { | ||
if (e === 'change') { | ||
this.change(this.filename); | ||
this.change(); | ||
} else if (e === 'rename') { | ||
@@ -188,3 +198,3 @@ this.rename(evtFilename); | ||
if (curr.size > prev.size) { | ||
this.pos = curr.size; //Update this.pos so that a consumer can determine if entire file has been handled | ||
this.currentCursorPos = curr.size; //Update this.currentCursorPos so that a consumer can determine if entire file has been handled | ||
this.queue.push({ start: prev.size, end: curr.size }); | ||
@@ -191,0 +201,0 @@ if (this.queue.length == 1) { |
@@ -17,3 +17,3 @@ { | ||
], | ||
"version": "2.1.1", | ||
"version": "2.2.0", | ||
"homepage": "https://www.lucagrulla.com/node-tail", | ||
@@ -20,0 +20,0 @@ "repository": { |
@@ -75,12 +75,13 @@ # Tail | ||
* `separator`: the line separator token (default: `/[\r]{0,1}\n/` to handle linux/mac (9+)/windows). Pass null if your file is binary there's no line separator. | ||
* `separator`: the line separator token (default: `/[\r]{0,1}\n/` to handle linux/mac (9+)/windows). Pass `null` for is binary files with no line separator. | ||
* `fsWatchOptions`: the full set of options that can be passed to `fs.watch` as per node documentation (default: {}). | ||
* `fromBeginning`: forces the tail of the file from the very beginning of it instead of from the first new line that will be appended (default: `false`). | ||
* `follow`: simulate `tail -F` option. In the case the file is moved/renamed (or logrotated), if set to `true` `tail` will try to start tailing again after a 1 second delay, if set to `false` it will just emit an error event (default: `true`). | ||
* `logger`: a logger object(default: no logger). The passed logger has to respond to two methods: | ||
* `fromBeginning`: tail from the beginning of the file (default: `false`). If `fromBeginning` is true `nLines` will be ignored. | ||
* `follow`: simulate `tail -F` option. In the case the file is moved/renamed/logrotated, if set to `true` will start tailing again after a 1 second delay; if set to `false` it will emit an error event (default: `true`). | ||
* `logger`: a logger object(default: no logger). The passed logger should follow the folliwing signature: | ||
* `info([data][, ...])` | ||
* `error([data][, ...])` | ||
* `useWatchFile`: if set to `true` will force the use of `fs.watchFile` rather than delegating to the library the choice between `fs.watch` and `fs.watchFile` (default: `false`). | ||
* `encoding`: the encoding of the file to tail (default:`utf-8`). | ||
* `flushAtEOF`: set to `true` if you want to force flush of content when end of file is reached. Particularly useful when there's no separator character at the end of the file (default: `false`). | ||
* `nLines`: tail from the last n lines. (default: `undefined`). Ignored if `fromBeginning` is set to `true`. | ||
* `useWatchFile`: if set to `true` will force the use of `fs.watchFile` over delegating to the library the choice between `fs.watch` and `fs.watchFile` (default: `false`). | ||
* `encoding`: the file encoding (default:`utf-8`). | ||
* `flushAtEOF`: set to `true` to force flush of content when end of file is reached. Useful when there's no separator character at the end of the file (default: `false`). | ||
@@ -109,3 +110,3 @@ ## Emitted events | ||
Tail is written in plain ES6.Pull Requests are welcome. | ||
Tail is written in ES6. Pull Requests are welcome. | ||
@@ -115,3 +116,3 @@ ## History | ||
Tail was born as part of a data firehose. Read about it [here](https://www.lucagrulla.com/posts/building-a-firehose-with-nodejs/). | ||
Tail original version was written in [CoffeeScript](https://coffeescript.org/). Since 2020 it's pure ES6. | ||
Tail original version was written in [CoffeeScript](https://coffeescript.org/). Since December 2020 it's pure ES6. | ||
@@ -118,0 +119,0 @@ ## License |
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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
13712
196
119
0