@vbarbarosh/node-helpers 3.58.1 → 3.60.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.58.1",
5
+ "version": "3.60.0",
6
6
  "description": "A set of helpers for JavaScript/Node.js",
7
7
  "files": [
8
8
  "src"
package/src/countdown.js CHANGED
@@ -1,3 +1,5 @@
1
+ const Promise = require('bluebird');
2
+
1
3
  /**
2
4
  * Wait for a promise/value to be settled. Meanwhile, call `tick` function every `tick_ms` milliseconds.
3
5
  * After `timeout` seconds, reject with 'Timeout' error.
@@ -10,7 +12,7 @@ function countdown(ctx)
10
12
  let done = false;
11
13
  let timer = null;
12
14
  return new Promise(function (resolve, reject) {
13
- ctx.value = Promise.resolve(ctx.value);
15
+ ctx.value = ctx.fn ? Promise.method(ctx.fn).call() : Promise.resolve(ctx.value);
14
16
  ctx.timeout = ctx.timeout || 0;
15
17
  ctx.time_now = new Date();
16
18
  ctx.time_begin = new Date();
@@ -0,0 +1,10 @@
1
+ function factorize_ms(v)
2
+ {
3
+ const h = Math.floor(v / 3600000);
4
+ const m = Math.floor(v % 3600000 / 60000);
5
+ const s = Math.floor(v % 60000 / 1000);
6
+ const ms = v % 1000;
7
+ return [h, m, s, ms];
8
+ }
9
+
10
+ module.exports = factorize_ms;
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @link https://stackoverflow.com/a/18650828
3
+ */
1
4
  function format_bytes(bytes)
2
5
  {
3
6
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
@@ -10,7 +13,7 @@ function format_bytes(bytes)
10
13
  if (bytes < 1024) {
11
14
  return '1KB';
12
15
  }
13
- const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10);
16
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
14
17
  return `${(bytes / (1024 ** i)).toFixed(bytes > 1024*1024 ? 2 : 0)}${sizes[i]}`.replace(/\.00/, '.0');
15
18
  }
16
19
 
@@ -0,0 +1,20 @@
1
+ const factorize_ms = require('./factorize_ms');
2
+
3
+ /**
4
+ * Format milliseconds
5
+ */
6
+ function format_ms(ms)
7
+ {
8
+ if (!ms) {
9
+ ms = 0;
10
+ }
11
+
12
+ // 00:05
13
+ const [h, m, s] = factorize_ms(ms);
14
+ if (h) {
15
+ return `0${h}:0${m}:0${s}`.replace(/0+(?=\d\d)/g, '');
16
+ }
17
+ return `0${m}:0${s}`.replace(/0+(?=\d\d)/g, '');
18
+ }
19
+
20
+ module.exports = format_ms;
@@ -0,0 +1,33 @@
1
+ const assert = require('assert');
2
+ const format_ms = require('./format_ms');
3
+ const msval = require('./msval');
4
+
5
+ const items = [
6
+ ['00:00', ''],
7
+ ['00:00', null],
8
+ ['00:00', undefined],
9
+ ['00:00', msval(0, 0, 0, 0)],
10
+ ['00:00', msval(0, 0, 0, 1)],
11
+ ['00:00', msval(0, 0, 0, 900)],
12
+ ['00:01', msval(0, 0, 1, 0)],
13
+ ['00:01', msval(0, 0, 1, 500)],
14
+ ['00:02', msval(0, 0, 2, 0)],
15
+ ['00:05', msval(0, 0, 5, 445)],
16
+ ['01:00', msval(0, 1, 0, 0)],
17
+ ['12:00', msval(0, 12, 0, 0)],
18
+ ['12:12', msval(0, 12, 12, 12)],
19
+ ['01:00:00', msval(1, 0, 0, 0)],
20
+ ['01:01:00', msval(1, 1, 0, 0)],
21
+ ['01:01:01', msval(1, 1, 1, 0)],
22
+ ['01:01:01', msval(1, 1, 1, 1)],
23
+ ['12:12:12', msval(12, 12, 12, 12)],
24
+ ['999:00:00', msval(999, 0, 0, 0)],
25
+ ];
26
+
27
+ describe('format_ms', function () {
28
+ items.forEach(function ([expected, input]) {
29
+ it(`${input} → ${expected}`, function () {
30
+ assert.strictEqual(format_ms(input), expected);
31
+ });
32
+ });
33
+ });
@@ -0,0 +1,20 @@
1
+ const factorize_ms = require('./factorize_ms');
2
+
3
+ /**
4
+ * Format milliseconds
5
+ */
6
+ function format_ms2(ms)
7
+ {
8
+ if (!ms) {
9
+ ms = 0;
10
+ }
11
+
12
+ // 00:05.45
13
+ const [h, m, s, xx] = factorize_ms(ms);
14
+ if (h) {
15
+ return `0${h}:0${m}:0${s}.0${Math.round(xx/10)}`.replace(/0+(?=\d\d)/g, '');
16
+ }
17
+ return `0${m}:0${s}.0${Math.round(xx/10)}`.replace(/0+(?=\d\d)/g, '');
18
+ }
19
+
20
+ module.exports = format_ms2;
@@ -0,0 +1,33 @@
1
+ const assert = require('assert');
2
+ const format_ms2 = require('./format_ms2');
3
+ const msval = require('./msval');
4
+
5
+ const items = [
6
+ ['00:00.00', ''],
7
+ ['00:00.00', null],
8
+ ['00:00.00', undefined],
9
+ ['00:00.00', msval(0, 0, 0, 0)],
10
+ ['00:00.00', msval(0, 0, 0, 1)],
11
+ ['00:00.90', msval(0, 0, 0, 900)],
12
+ ['00:01.00', msval(0, 0, 1, 0)],
13
+ ['00:01.50', msval(0, 0, 1, 500)],
14
+ ['00:02.00', msval(0, 0, 2, 0)],
15
+ ['00:05.45', msval(0, 0, 5, 445)],
16
+ ['01:00.00', msval(0, 1, 0, 0)],
17
+ ['12:00.00', msval(0, 12, 0, 0)],
18
+ ['12:12.01', msval(0, 12, 12, 12)],
19
+ ['01:00:00.00', msval(1, 0, 0, 0)],
20
+ ['01:01:00.00', msval(1, 1, 0, 0)],
21
+ ['01:01:01.00', msval(1, 1, 1, 0)],
22
+ ['01:01:01.00', msval(1, 1, 1, 1)],
23
+ ['12:12:12.01', msval(12, 12, 12, 12)],
24
+ ['999:00:00.00', msval(999, 0, 0, 0)],
25
+ ];
26
+
27
+ describe('format_ms2', function () {
28
+ items.forEach(function ([expected, input]) {
29
+ it(`${input} → ${expected}`, function () {
30
+ assert.strictEqual(format_ms2(input), expected);
31
+ });
32
+ });
33
+ });
@@ -0,0 +1,20 @@
1
+ const factorize_ms = require('./factorize_ms');
2
+
3
+ /**
4
+ * Format milliseconds
5
+ */
6
+ function format_ms3(ms)
7
+ {
8
+ if (!ms) {
9
+ ms = 0;
10
+ }
11
+
12
+ // 00:05.445
13
+ const [h, m, s, xx] = factorize_ms(ms);
14
+ if (h) {
15
+ return `0${h}:0${m}:0${s}.00${xx}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g, '');
16
+ }
17
+ return `0${m}:0${s}.00${xx}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g, '')
18
+ }
19
+
20
+ module.exports = format_ms3;
@@ -0,0 +1,33 @@
1
+ const assert = require('assert');
2
+ const format_ms3 = require('./format_ms3');
3
+ const msval = require('./msval');
4
+
5
+ const items = [
6
+ ['00:00.000', ''],
7
+ ['00:00.000', null],
8
+ ['00:00.000', undefined],
9
+ ['00:00.000', msval(0, 0, 0, 0)],
10
+ ['00:00.001', msval(0, 0, 0, 1)],
11
+ ['00:00.900', msval(0, 0, 0, 900)],
12
+ ['00:01.000', msval(0, 0, 1, 0)],
13
+ ['00:01.500', msval(0, 0, 1, 500)],
14
+ ['00:02.000', msval(0, 0, 2, 0)],
15
+ ['00:05.445', msval(0, 0, 5, 445)],
16
+ ['01:00.000', msval(0, 1, 0, 0)],
17
+ ['12:00.000', msval(0, 12, 0, 0)],
18
+ ['12:12.012', msval(0, 12, 12, 12)],
19
+ ['01:00:00.000', msval(1, 0, 0, 0)],
20
+ ['01:01:00.000', msval(1, 1, 0, 0)],
21
+ ['01:01:01.000', msval(1, 1, 1, 0)],
22
+ ['01:01:01.001', msval(1, 1, 1, 1)],
23
+ ['12:12:12.012', msval(12, 12, 12, 12)],
24
+ ['999:00:00.000', msval(999, 0, 0, 0)],
25
+ ];
26
+
27
+ describe('format_ms3', function () {
28
+ items.forEach(function ([expected, input]) {
29
+ it(`${input} → ${expected}`, function () {
30
+ assert.strictEqual(format_ms3(input), expected);
31
+ });
32
+ });
33
+ });
package/src/fs_append.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
 
3
- function fs_append(file, data, options = {})
3
+ function fs_append(file, data, options)
4
4
  {
5
5
  return fs.promises.appendFile(file, data, options);
6
6
  }
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
 
3
- function fs_append_utf8(file, text, options = {})
3
+ function fs_append_utf8(file, text, options)
4
4
  {
5
5
  return fs.promises.appendFile(file, text, options);
6
6
  }
package/src/fs_copy.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.copyFile);
3
+ function fs_copy(src, dest, mode)
4
+ {
5
+ return fs.promises.copyFile(src, dest, mode);
6
+ }
7
+
8
+ module.exports = fs_copy;
package/src/fs_exists.js CHANGED
@@ -3,9 +3,7 @@ const fs = require('fs');
3
3
  async function fs_exists(path)
4
4
  {
5
5
  return new Promise(function (resolve) {
6
- fs.access(path, function (error) {
7
- error ? resolve(false) : resolve(true);
8
- });
6
+ fs.access(path, error => resolve(!error));
9
7
  });
10
8
  }
11
9
 
package/src/fs_lstat.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.lstat);
3
+ function fs_lstat(path, options)
4
+ {
5
+ return fs.promises.lstat(path, options);
6
+ }
7
+
8
+ module.exports = fs_lstat;
package/src/fs_mkdir.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.mkdir);
3
+ function fs_mkdir(path, options)
4
+ {
5
+ return fs.promises.mkdir(path, options);
6
+ }
7
+
8
+ module.exports = fs_mkdir;
package/src/fs_mkdirp.js CHANGED
@@ -6,7 +6,7 @@ async function fs_mkdirp(pathname)
6
6
  {
7
7
  const parents = [];
8
8
 
9
- for (let p = pathname; p && p != '/'; p = fs_path_dirname(p)) {
9
+ for (let p = pathname; p && p !== '/'; p = fs_path_dirname(p)) {
10
10
  if (await fs_exists(p)) {
11
11
  break;
12
12
  }
package/src/fs_read.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.readFile);
3
+ function fs_read(path, options)
4
+ {
5
+ return fs.promises.readFile(path, options);
6
+ }
7
+
8
+ module.exports = fs_read;
@@ -1,3 +1,8 @@
1
1
  const fs = require('fs');
2
2
 
3
- module.exports = fs.createReadStream;
3
+ function fs_read_stream(path, options)
4
+ {
5
+ return fs.createReadStream(path, options);
6
+ }
7
+
8
+ module.exports = fs_read_stream;
package/src/fs_readdir.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.readdir);
3
+ function fs_readdir(path, options)
4
+ {
5
+ return fs.promises.readdir(path, options);
6
+ }
7
+
8
+ module.exports = fs_readdir;
package/src/fs_rm.js CHANGED
@@ -1,18 +1,11 @@
1
- const Promise = require('bluebird');
2
1
  const fs = require('fs');
3
2
 
4
3
  /**
5
4
  * Remove a file
6
- *
7
- * @link https://nodejs.org/api/fs.html#fsunlinkpath-callback
8
5
  */
9
- async function fs_rm(filename)
6
+ function fs_rm(path)
10
7
  {
11
- await new Promise(function (resolve, reject) {
12
- fs.unlink(filename, function (error) {
13
- error ? reject(error) : resolve();
14
- });
15
- });
8
+ return fs.promises.unlink(path);
16
9
  }
17
10
 
18
11
  module.exports = fs_rm;
package/src/fs_rmdir.js CHANGED
@@ -1,5 +1,8 @@
1
1
  const fs = require('fs');
2
- const util = require('util');
3
2
 
4
- // https://nodejs.org/api/util.html#util_util_promisify_original
5
- module.exports = util.promisify(fs.rmdir);
3
+ function fs_rmdir(path)
4
+ {
5
+ return fs.promises.rmdir(path);
6
+ }
7
+
8
+ module.exports = fs_rmdir;
package/src/fs_rmf.js CHANGED
@@ -1,13 +1,17 @@
1
- const fs_exists = require('./fs_exists');
2
1
  const fs_rm = require('./fs_rm');
3
2
 
4
3
  /**
5
4
  * Remove the file if it exists.
6
5
  */
7
- async function fs_rmf(filename)
6
+ async function fs_rmf(path)
8
7
  {
9
- if (await fs_exists(filename)) {
10
- await fs_rm(filename);
8
+ try {
9
+ await fs_rm(path);
10
+ }
11
+ catch (error) {
12
+ if (error.code !== 'ENOENT') {
13
+ throw error;
14
+ }
11
15
  }
12
16
  }
13
17
 
package/src/fs_rmrf.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const Promise = require('bluebird');
2
- const fs_fi = require('./fs_fi');
2
+ const fs_lstat = require('./fs_lstat');
3
3
  const fs_path_resolve = require('./fs_path_resolve');
4
4
  const fs_readdir = require('./fs_readdir');
5
5
  const fs_rm = require('./fs_rm');
@@ -8,20 +8,20 @@ const fs_rmdir = require('./fs_rmdir');
8
8
  /**
9
9
  * Remove a file or directory, along with all nested files and directories, recursively.
10
10
  */
11
- async function fs_rmrf(pathname)
11
+ async function fs_rmrf(path)
12
12
  {
13
- const fi = await fs_fi(pathname).catch(() => null);
14
- if (fi === null) {
13
+ const lstat = await fs_lstat(path).catch(() => null);
14
+ if (lstat === null) {
15
15
  return;
16
16
  }
17
17
 
18
- if (fi.isDirectory()) {
19
- const names = await fs_readdir(pathname);
20
- await Promise.all(names.map(v => fs_rmrf(fs_path_resolve(pathname, v))));
21
- await fs_rmdir(fi.pathname);
18
+ if (lstat.isDirectory()) {
19
+ const names = await fs_readdir(path);
20
+ await Promise.all(names.map(v => fs_rmrf(fs_path_resolve(path, v))));
21
+ await fs_rmdir(path);
22
22
  }
23
23
  else {
24
- await fs_rm(fi.pathname);
24
+ await fs_rm(path);
25
25
  }
26
26
  }
27
27
 
package/src/fs_write.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
 
3
- async function fs_write(file, data, options = {})
3
+ function fs_write(file, data, options)
4
4
  {
5
5
  return fs.promises.writeFile(file, data, options);
6
6
  }
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
 
3
- async function fs_write_json(file, data)
3
+ function fs_write_json(file, data)
4
4
  {
5
5
  return fs.promises.writeFile(file, JSON.stringify(data, null, 4));
6
6
  }
@@ -1,3 +1,8 @@
1
1
  const fs = require('fs');
2
2
 
3
- module.exports = fs.createWriteStream;
3
+ function fs_write_stream(path, options)
4
+ {
5
+ return fs.createWriteStream(path, options);
6
+ }
7
+
8
+ module.exports = fs_write_stream;
package/src/msval.js ADDED
@@ -0,0 +1,6 @@
1
+ function msval(h, m, s, ms)
2
+ {
3
+ return h*3600000 + m*60000 + s*1000 + ms;
4
+ }
5
+
6
+ module.exports = msval;
@@ -0,0 +1,11 @@
1
+ function object_defaults(obj, defaults)
2
+ {
3
+ Object.entries(defaults).forEach(function ([key, value]) {
4
+ if (obj[key] === undefined) {
5
+ obj[key] = value;
6
+ }
7
+ });
8
+ return obj;
9
+ }
10
+
11
+ module.exports = object_defaults;
@@ -6,14 +6,19 @@ const stream = require('stream');
6
6
  /**
7
7
  * Monitor the progress of data through a pipe, similar to the UNIX `pv` command.
8
8
  *
9
+ * Requirements:
10
+ * - should emit first message as fast as possible
11
+ * - should always emit 100% message
12
+ *
9
13
  * @similar https://www.npmjs.com/package/progress-stream
10
14
  */
11
- function stream_progress({objectMode = false, total, user_friendly_status = s => console.log(s)} = {})
15
+ function stream_progress({objectMode = false, interval = 1000, total, user_friendly_status = s => console.log(s)} = {})
12
16
  {
13
17
  let done = 0;
14
- const timer = setInterval(tick, 1000);
18
+ const timer = setInterval(tick, interval);
15
19
  const progress = make_progress(total);
16
20
  const format_progress = objectMode ? format_progress_kilo : format_progress_bytes;
21
+ setTimeout(tick, 0);
17
22
  return new stream.Transform({
18
23
  objectMode,
19
24
  destroy: function (error, callback) {