@vbarbarosh/node-helpers 3.41.1 → 3.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "author": "Vladimir Barbarosh <vladimir.barbarosh@gmail.com>",
3
3
  "license": "MIT",
4
4
  "name": "@vbarbarosh/node-helpers",
5
- "version": "3.41.1",
5
+ "version": "3.43.0",
6
6
  "description": "A set of helpers for JavaScript/Node.js",
7
7
  "files": [
8
8
  "src"
@@ -1,9 +1,10 @@
1
1
  const fs_fopen = require('./fs_fopen');
2
2
 
3
- // Main use case is uploading files in chunks. Each time
4
- // a chunk is uploaded do update a target file. At the end
5
- // you will have a ready to go file.
6
-
3
+ /**
4
+ * The main use case is uploading files in chunks.
5
+ * Each time a chunk is uploaded, update the target file.
6
+ * By the end, you will have a ready-to-use file.
7
+ */
7
8
  async function fs_fopen_update(pathname)
8
9
  {
9
10
  try {
@@ -11,23 +12,22 @@ async function fs_fopen_update(pathname)
11
12
  return await fs_fopen(pathname, 'r+');
12
13
  }
13
14
  catch (error) {
14
- if (error.code != 'ENOENT') {
15
+ if (error.code !== 'ENOENT') {
15
16
  throw error;
16
17
  }
17
18
  }
18
19
 
19
20
  try {
20
- // There is no such a file, try to create it...
21
+ // There is no such file; try to create it...
21
22
  return await fs_fopen(pathname, 'wx');
22
23
  }
23
24
  catch (error) {
24
- if (error.code != 'EEXIST') {
25
+ if (error.code !== 'EEXIST') {
25
26
  throw error;
26
27
  }
27
28
  }
28
29
 
29
- // Another process might have already created it, try to
30
- // open for updating...
30
+ // Another process might have already created it; try opening it for updating
31
31
  return fs_fopen(pathname, 'r+');
32
32
  }
33
33
 
package/src/fs_fread.js CHANGED
@@ -1,15 +1,16 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
-
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- const read = util.promisify(fs.read);
6
-
7
- // Main use case is for reading chunks of data from file.
8
2
 
3
+ /**
4
+ * The main use case is reading chunks of data from a file.
5
+ */
9
6
  async function fs_fread(fp, buffer, offset = null)
10
7
  {
11
- const {bytesRead} = await read(fp, buffer, 0, buffer.length, offset);
12
- return (bytesRead == buffer.length) ? buffer : buffer.slice(0, bytesRead);
8
+ const {bytesRead} = await new Promise(function (resolve, reject) {
9
+ fs.read(fp, buffer, 0, buffer.length, offset, function (error, out) {
10
+ error ? reject(error) : resolve(out);
11
+ });
12
+ });
13
+ return (bytesRead === buffer.length) ? buffer : buffer.slice(0, bytesRead);
13
14
  }
14
15
 
15
16
  module.exports = fs_fread;
package/src/fs_fwrite.js CHANGED
@@ -1,14 +1,15 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
-
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- const write = util.promisify(fs.write);
6
-
7
- // Main use case is for writing chunks of data to file.
8
2
 
3
+ /**
4
+ * The main use case is writing chunks of data to a file.
5
+ */
9
6
  async function fs_fwrite(fp, buffer, offset = null)
10
7
  {
11
- const {bytesWritten} = await write(fp, buffer, 0, buffer.length, offset);
8
+ const {bytesWritten} = await new Promise(function (resolve, reject) {
9
+ fs.write(fp, buffer, 0, buffer.length, offset, function (error, out) {
10
+ error ? reject(error) : resolve(out);
11
+ });
12
+ });
12
13
  return bytesWritten;
13
14
  }
14
15
 
@@ -1,5 +1,8 @@
1
1
  const fs_read = require('./fs_read');
2
2
 
3
+ /**
4
+ * Read the entire contents of a file into a buffer.
5
+ */
3
6
  function fs_read_buffer(file)
4
7
  {
5
8
  return fs_read(file);
@@ -1,5 +1,8 @@
1
1
  const fs_read = require('./fs_read');
2
2
 
3
+ /**
4
+ * Read the entire contents of a file into a UTF-8 encoded string.
5
+ */
3
6
  function fs_read_utf8(file)
4
7
  {
5
8
  return fs_read(file, {encoding: 'utf8'});
package/src/fs_rmrf.js CHANGED
@@ -5,6 +5,9 @@ const fs_readdir = require('./fs_readdir');
5
5
  const fs_rm = require('./fs_rm');
6
6
  const fs_rmdir = require('./fs_rmdir');
7
7
 
8
+ /**
9
+ * Remove a file or directory, along with all nested files and directories, recursively.
10
+ */
8
11
  async function fs_rmrf(pathname)
9
12
  {
10
13
  const fi = await fs_fi(pathname).catch(() => null);
@@ -1,10 +1,8 @@
1
1
  const fs = require('fs');
2
2
 
3
3
  /**
4
- * Returns size of a file, or 0 if file is not present. Was created for cases
5
- * when you need to resume download.
6
- *
7
- * @returns {Promise<int>}
4
+ * Returns the size of a file, or 0 if the file is not present.
5
+ * It was created for cases when you need to resume a download.
8
6
  */
9
7
  async function fs_size_enoent(path)
10
8
  {
@@ -0,0 +1,8 @@
1
+ const format_hrtime = require('./format_hrtime');
2
+
3
+ function perf_end_human(time0, digits = 4)
4
+ {
5
+ return format_hrtime(time0, digits);
6
+ }
7
+
8
+ module.exports = perf_end_human;
@@ -0,0 +1,7 @@
1
+ function perf_end_ms(time0)
2
+ {
3
+ const [u, v] = process.hrtime(time0);
4
+ return Math.round((u + v/1E9)*1000);
5
+ }
6
+
7
+ module.exports = perf_end_ms;
@@ -0,0 +1,11 @@
1
+ const perf_end_human = require('./perf_end_human');
2
+ const perf_start = require('./perf_start');
3
+
4
+ async function perf_measure_human(fn, digits = 4)
5
+ {
6
+ const time0 = perf_start();
7
+ await fn();
8
+ return perf_end_human(time0, digits);
9
+ }
10
+
11
+ module.exports = perf_measure_human;
@@ -0,0 +1,6 @@
1
+ function perf_start()
2
+ {
3
+ return process.hrtime();
4
+ }
5
+
6
+ module.exports = perf_start;
@@ -0,0 +1,27 @@
1
+ const stream = require('stream');
2
+
3
+ /**
4
+ * Split a stream into chunks of objects.
5
+ */
6
+ function stream_chunk(chunk_size)
7
+ {
8
+ const chunk = [];
9
+ return new stream.Transform({
10
+ objectMode: true,
11
+ transform: function (item, encoding, callback) {
12
+ chunk.push(item);
13
+ if (chunk.length >= chunk_size) {
14
+ this.push(chunk.splice(0));
15
+ }
16
+ callback();
17
+ },
18
+ flush: function (callback) {
19
+ if (chunk.length) {
20
+ this.push(chunk.splice(0));
21
+ }
22
+ callback();
23
+ },
24
+ });
25
+ }
26
+
27
+ module.exports = stream_chunk;
@@ -3,14 +3,13 @@ const fs = require('fs');
3
3
  const split = require('split');
4
4
  const stream = require('stream');
5
5
  const stream_data_ln = require('./stream_data_ln');
6
- const stream_promise = require('./stream_promise');
7
6
 
8
7
  describe('stream_data_ln', function () {
9
8
  it('should handle basic input', async function () {
10
9
  let actual = '';
11
10
  const s = fs.createReadStream(__filename);
12
11
  const off = stream_data_ln(s, v => actual += v + '\n');
13
- await stream_promise(s);
12
+ await stream.promises.finished(s);
14
13
  off();
15
14
  assert.deepStrictEqual(actual, fs.readFileSync(__filename, {encoding: 'utf8'}));
16
15
  });
@@ -7,9 +7,14 @@ function stream_each(fn)
7
7
  {
8
8
  return stream.Writable({
9
9
  objectMode: true,
10
- write: function (item, encoding, callback) {
11
- fn(item);
12
- callback();
10
+ write: async function (item, encoding, callback) {
11
+ try {
12
+ await fn(item);
13
+ callback();
14
+ }
15
+ catch (error) {
16
+ callback(error);
17
+ }
13
18
  }
14
19
  });
15
20
  }
@@ -7,9 +7,9 @@ function stream_filter(fn)
7
7
  {
8
8
  return new stream.Transform({
9
9
  objectMode: true,
10
- transform: function (item, encoding, callback) {
10
+ transform: async function (item, encoding, callback) {
11
11
  try {
12
- if (fn(item)) {
12
+ if (await fn(item)) {
13
13
  this.push(item);
14
14
  }
15
15
  callback();
@@ -1,29 +1,13 @@
1
- const stream = require('stream');
1
+ const stream_chunk = require('./stream_chunk');
2
2
 
3
3
  /**
4
- * Returns a transform stream used to group object into chunks of objects.
4
+ * Split a stream into chunks of objects.
5
5
  *
6
- * TODO Rename to stream_chunk
6
+ * @deprecated Deprecated in favor of `stream_chunk`
7
7
  */
8
8
  function stream_group(chunk_size)
9
9
  {
10
- const chunk = [];
11
- return new stream.Transform({
12
- objectMode: true,
13
- transform: function (item, encoding, callback) {
14
- chunk.push(item);
15
- if (chunk.length >= chunk_size) {
16
- this.push(chunk.splice(0));
17
- }
18
- callback();
19
- },
20
- flush: function (callback) {
21
- if (chunk.length) {
22
- this.push(chunk.splice(0));
23
- }
24
- callback();
25
- },
26
- });
10
+ return stream_chunk(chunk_size);
27
11
  }
28
12
 
29
13
  module.exports = stream_group;
package/src/stream_map.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const stream = require('stream');
2
2
 
3
3
  /**
4
- * Transform each item by simple function.
4
+ * Transform each item using a simple function.
5
5
  */
6
6
  function stream_map(fn)
7
7
  {
@@ -2,7 +2,7 @@ const Promise = require('bluebird');
2
2
  const stream = require('stream');
3
3
 
4
4
  /**
5
- * Transform each item by simple function in parallel.
5
+ * Transform each item using a simple function in parallel.
6
6
  */
7
7
  function stream_map_parallel({handler, concurrency})
8
8
  {
@@ -3,7 +3,7 @@ const make_progress = require('./make_progress');
3
3
  const stream = require('stream');
4
4
 
5
5
  /**
6
- * Monitor the progress of data through a pipe. Similar to UNIX `pv` command.
6
+ * Monitor the progress of data through a pipe, similar to the UNIX `pv` command.
7
7
  *
8
8
  * @similar https://www.npmjs.com/package/progress-stream
9
9
  */
@@ -1,7 +1,7 @@
1
1
  const stream = require('stream');
2
2
 
3
3
  /**
4
- * Split input stream by consecutive delimiters in `chars`.
4
+ * Split the input stream by consecutive delimiters in `chars`
5
5
  */
6
6
  function stream_strpbrk(chars = '\r\n')
7
7
  {
@@ -0,0 +1,23 @@
1
+ const stream = require('stream');
2
+
3
+ /**
4
+ * Call `fn` on each item.
5
+ */
6
+ function stream_tap(fn)
7
+ {
8
+ return new stream.Transform({
9
+ objectMode: true,
10
+ transform: async function (item, encoding, callback) {
11
+ try {
12
+ await fn(item);
13
+ this.push(item, encoding);
14
+ callback();
15
+ }
16
+ catch (error) {
17
+ callback(error);
18
+ }
19
+ },
20
+ });
21
+ }
22
+
23
+ module.exports = stream_tap;
@@ -1,23 +1,13 @@
1
- const stream = require('stream');
1
+ const stream_tap = require('./stream_tap');
2
2
 
3
3
  /**
4
4
  * Call `fn` on each item.
5
+ *
6
+ * @deprecated Deprecated in favor of `stream_tap`.
5
7
  */
6
8
  function stream_through(fn)
7
9
  {
8
- return new stream.Transform({
9
- objectMode: true,
10
- transform: function (item, encoding, callback) {
11
- try {
12
- fn(item);
13
- this.push(item, encoding);
14
- callback();
15
- }
16
- catch (error) {
17
- callback(error);
18
- }
19
- },
20
- });
10
+ return stream_tap(fn);
21
11
  }
22
12
 
23
13
  module.exports = stream_through;
@@ -1,22 +1,11 @@
1
- const stream = require('stream');
1
+ const stream_map = require('./stream_map');
2
2
 
3
3
  /**
4
- * @deprecated Deprecated in favor of stream_map
4
+ * @deprecated Deprecated in favor of `stream_map`
5
5
  */
6
6
  function stream_transform(fn)
7
7
  {
8
- return new stream.Transform({
9
- objectMode: true,
10
- transform: function (item, encoding, next) {
11
- try {
12
- this.push(fn(item));
13
- next();
14
- }
15
- catch (error) {
16
- next(error);
17
- }
18
- },
19
- });
8
+ return stream_map(fn);
20
9
  }
21
10
 
22
11
  module.exports = stream_transform;
@@ -1,63 +0,0 @@
1
- const {finished} = require('stream/promises');
2
-
3
- // /**
4
- // * Wait for a stream to finish with `await stream_promise(stream)`.
5
- // *
6
- // * @param stream
7
- // * @returns {Promise}
8
- // */
9
- // function stream_promise(stream)
10
- // {
11
- // /**
12
- // * https://stackoverflow.com/a/34310963/1478566
13
- // * > end and finish are the same event BUT on different types of
14
- // * > Streams.
15
- // * > * stream.Readable fires ONLY end and NEVER finish
16
- // * > * stream.Writable fires ONLY finish and NEVER end
17
- // */
18
- // return new Promise(function (resolve, reject) {
19
- // stream.once('end', resolve); // Stream.Readable
20
- // stream.once('finish', resolve); // Stream.Writable
21
- // stream.once('error', reject);
22
- // function end() { off(); resolve(); }
23
- // function finish() { off(); resolve(); }
24
- // function error() { off(); reject(); }
25
- // function off() {
26
- // stream.off('end', end);
27
- // stream.off('finish', finish);
28
- // stream.off('error', error);
29
- // }
30
- // });
31
- // }
32
-
33
- /**
34
- * Wait for a stream to finish with `await stream_promise(stream)`.
35
- *
36
- * https://nodejs.org/api/stream.html#stream_stream_finished_stream_options_callback
37
- * > Especially useful in error handling scenarios where a stream
38
- * > is destroyed prematurely (like an aborted HTTP request), and
39
- * > will not emit 'end' or 'finish'.
40
- *
41
- * @param stream
42
- * @returns {Promise<void>}
43
- * @deprecated Deprecated in favor of `stream.promises.finished`. Should be removed in the next major release.
44
- */
45
- function stream_promise(stream)
46
- {
47
- // https://nodejs.org/api/stream.html#stream_stream_finished_stream_options_callback
48
- // > stream.finished() leaves dangling event listeners (in particular
49
- // > 'error', 'end', 'finish' and 'close') after callback has been
50
- // > invoked. The reason for this is so that unexpected 'error'
51
- // > events (due to incorrect stream implementations) do not cause
52
- // > unexpected crashes. If this is unwanted behavior then the
53
- // > returned cleanup function needs to be invoked in the callback:
54
- // >
55
- // > const cleanup = finished(rs, (err) => {
56
- // > cleanup();
57
- // > // ...
58
- // > });
59
- // >
60
- return finished(stream);
61
- }
62
-
63
- module.exports = stream_promise;
@@ -1,14 +0,0 @@
1
- const fs = require('fs');
2
- const ignore = require('./ignore');
3
- const stream_promise = require('./stream_promise');
4
-
5
- describe('stream_promise', function () {
6
- it('should handle ReadableStream', async function () {
7
- this.timeout(100);
8
- await stream_promise(fs.createReadStream(__filename).on('data', ignore));
9
- });
10
- it('should handle WritableStream', async function () {
11
- this.timeout(100);
12
- await stream_promise(fs.createWriteStream('/dev/null').end('hello\n'));
13
- });
14
- });