necessary 14.3.2 → 14.4.1

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/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  A collection of utility functions.
4
4
 
5
- This package was partly inspired by [lodash](https://lodash.com/), [async](https://caolan.github.io/async/) and the like. The idea was to create utility functions that addressed some modest requirements and would result in a relatively small footprint. That said, the bare bones implementations, especially the asynchronous functions, should provide some confidence whilst debugging.
5
+ This package was partly inspired by [lodash](https://lodash.com/), [async](https://caolan.github.io/async/) and the like.
6
+ The idea was to create utility functions that addressed some modest requirements and would result in a relatively small footprint.
7
+ That said, the bare bones implementations, especially the asynchronous functions, should provide some confidence whilst debugging.
6
8
 
7
9
  These can only be used in the browser:
8
10
 
@@ -43,7 +45,8 @@ You can also clone the repository with [Git](https://git-scm.com/)...
43
45
 
44
46
  ## Usage
45
47
 
46
- Each of the collections of utility functions described below is exported as a plain old JavaScript object. To get hold of them, import the requisite object and then destructure it:
48
+ Each of the collections of utility functions described below is exported as a plain old JavaScript object.
49
+ To get hold of them, import the requisite object and then destructure it:
47
50
 
48
51
  ```
49
52
  import { arrayUtilities, asynchronousUtilities, fileSystemUtilities } from "necessary";
@@ -65,23 +68,28 @@ const { first, last } = arrayUtilities,
65
68
  ...
66
69
  ```
67
70
 
68
- The miscellaneous functions are a special case. They can be treated as above but may well have other functions assigned to them. See below.
71
+ The miscellaneous functions are a special case.
72
+ They can be treated as above but may well have other functions assigned to them.
73
+ See below.
69
74
 
70
75
  ## Ajax utilities
71
76
 
72
77
  - `get()`
73
- - `post()`cp
78
+ - `post()`
74
79
  - `request()`
75
80
 
76
81
  The first two `get()` and `post()` functions make use of the third `request()` function, which is more generic and can be used for arbitrary HTTP requests.
77
82
 
78
- * The `get()` function sends a `GET` request, taking `host`, `uri`, `query` and `operation` arguments, together with an optional `headers` argument after the `query` argument.
83
+ * The `get()` function sends a `GET` request, taking `host`, `uri` and `query` arguments, together with an optional `headers` argument after the `query` argument.
79
84
 
80
85
  The `query` argument should be a plain old JavaScript object, the names and values of which are encoded and concatenated to form the query string.
81
86
 
82
- The `headers` argument should also be a plain old JavaScript object. If it does not have an `accept` property then one wil be provided with the value `application/json`.
87
+ The `headers` argument should also be a plain old JavaScript object.
88
+ If it does not have an `accept` property then one wil be provided with the value `application/json`.
83
89
 
84
- The `callback` argument is expected to be a function taking `content` and `statusCode` arguments. If the `accept` property of the main `headers` argument is set to `application/json` then the operation's `content` argument can be assumed to be JSON, or `null` if the request body cannot be parsed as such. The `statusCode` argument will be the response status code, for example `200` for a successful `OK` response.
90
+ The `callback` argument is expected to be a function taking `content` and `statusCode` arguments.
91
+ If the `accept` property of the main `headers` argument is set to `application/json` then the function's `content` argument can be assumed to be JSON, or `null` if the request body cannot be parsed as such.
92
+ The `statusCode` argument will be the response status code, for example `200` for a successful `OK` response.
85
93
 
86
94
  ```
87
95
  const host = "...",
@@ -101,7 +109,10 @@ Note that the `uri` argument must include a leading forward slash `/` since the
101
109
 
102
110
  * The `post()` function behaves almost identically to the `get()` function, with the following differences.
103
111
 
104
- It sends a `POST` rather than a `GET` request. There is an additional `content` argument that comes before the `callabck` argument and after the `headers` argument, which is again optional. If the `headers` argument does not have a `content-type` property then one will be provided with the value of `application/json`. If the `content-type` property of the `headers` argument is set to `application/json` then the `content` argument is assumed to be a plain old JavaScript object and is stringified as JSON.
112
+ It sends a `POST` rather than a `GET` request.
113
+ There is an additional `content` argument that comes before the `callabck` argument and after the `headers` argument, which is again optional.
114
+ If the `headers` argument does not have a `content-type` property then one will be provided with the value of `application/json`.
115
+ If the `content-type` property of the `headers` argument is set to `application/json` then the `content` argument is assumed to be a plain old JavaScript object and is stringified as JSON.
105
116
 
106
117
  ```
107
118
  const host = "...",
@@ -152,7 +163,8 @@ Note that the `headers` argument is not optional this time.
152
163
  Functions for applications running on a shell such as Bash or ZSH.
153
164
  In fact there is only one currently.
154
165
 
155
- * The `prompt()` function is meant for use in shell applications. It takes a plain old JavaScript `options` object and a `callback` function as its first and second arguments, respectively:
166
+ * The `prompt()` function is meant for use in shell applications.
167
+ It takes a plain old JavaScript `options` object and a `callback` function as its first and second arguments, respectively:
156
168
 
157
169
  ```
158
170
  const hidden = true,
@@ -173,13 +185,18 @@ prompt(options, (answer) => {
173
185
  });
174
186
  ```
175
187
 
176
- There are a range of properties available for the `options` object. The `description` and `errorMessage` properties are mandatory. The remaining properties are optional.
188
+ There are a range of properties available for the `options` object.
189
+ The `description` and `errorMessage` properties are mandatory.
190
+ The remaining properties are optional.
177
191
 
178
- The default values of the `attempts` and `encoding` properties are `3` and `utf8`, respectively. The default value of the `hidden` property is `false`. Setting it to `true` results in password-style input, that is, the characters remain hidden.
192
+ The default values of the `attempts` and `encoding` properties are `3` and `utf8`, respectively.
193
+ The default value of the `hidden` property is `false`. Setting it to `true` results in password-style input, that is, the characters remain hidden.
179
194
 
180
195
  If no `validateFunction` property is given then you must set a `validatePattern` property instead, which must be a regular expression.
181
196
 
182
- The `initialAnswer` property sets the initial answer at the prompt. You might want to set it to `yes`, for example. Lastly, setting the `answer` property to anything other than `null` or `undefined` causes the `callback` function to be invoked immediately without any prompt being shown. This can be useful for debugging.
197
+ The `initialAnswer` property sets the initial answer at the prompt.
198
+ You might want to set it to `yes`, for example. Lastly, setting the `answer` property to anything other than `null` or `undefined` causes the `callback` function to be invoked immediately without any prompt being shown.
199
+ This can be useful for debugging.
183
200
 
184
201
  ## Logging utilities
185
202
 
@@ -195,7 +212,9 @@ log("...") // Results in '28-01-2018 15:44:47.363 bin/main.js(35) ...' being log
195
212
 
196
213
  You can pass an error instead of a string to `log()`, in which case it will print the file path and line number of the place where the error was thrown along with the error message.
197
214
 
198
- Additionally, it is possible to print to a log file if a log directory and, optionally, a base name for the log file are specified. The base name here means the file name minus the extension and separator. The default is `default`:
215
+ Additionally, it is possible to print to a log file if a log directory and, optionally, a base name for the log file are specified.
216
+ The base name here means the file name minus the extension and separator.
217
+ The default is `default`:
199
218
 
200
219
  ```
201
220
  const { setLogFileBaseName, setLogDirectoryPath } = log;
@@ -218,7 +237,8 @@ log.error("...") // Printed to the console and optionally, to the log file.
218
237
  log.trace("...") // Ignored, because the trace level is lower than the debug level.
219
238
  ```
220
239
 
221
- There is also a `setLogOptions()` function which allows you to pass the log level, base file name and directory path as a plain old JavaScript object. See below for a usage example.
240
+ There is also a `setLogOptions()` function which allows you to pass the log level, base file name and directory path as a plain old JavaScript object.
241
+ See below for a usage example.
222
242
 
223
243
  Finally, log files are rolled over every night. So `./log/example.log` would become `./log/example.28-01-2018.log` and a new `./log/example.log` file would be started at midnight.
224
244
 
@@ -228,11 +248,21 @@ Finally, log files are rolled over every night. So `./log/example.log` would bec
228
248
  - `createGetRequest()`
229
249
  - `createPostRequest()`
230
250
 
231
- Functions that leverage Node's [HTTP](https://nodejs.org/api/http.html) nad [HTTPS](https://nodejs.org/api/https.html) inbuilt modules in order to provide HTTP request functionality. These functions are deliberately low level. They will take away some of the pain of using the aforementioned modules but will not automatically set headers, parse responses, etc. Specifically, methods have to be called on the instance of the [ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest) class that they each return in order to make the request and on the instance of the [IncomingMessage](https://nodejs.org/api/http.html#class-httpincomingmessage) passed to the callback function in order to parse the response.
251
+ Functions that leverage Node's [HTTP](https://nodejs.org/api/http.html) nad [HTTPS](https://nodejs.org/api/https.html) inbuilt modules in order to provide HTTP request functionality.
252
+ These functions are deliberately low level.
253
+ They will take away some of the pain of using the aforementioned modules but will not automatically set headers, parse responses, etc.
254
+ Specifically, methods have to be called on the instance of the [ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest) class that they each return in order to make the request and on the instance of the [IncomingMessage](https://nodejs.org/api/http.html#class-httpincomingmessage) passed to the callback function in order to parse the response.
232
255
 
233
- * The `createRequest()` function provides a means to make arbitrary requests. It takes `host`, `uri`, `query`, `method`, `headers` and `callback` arguments. It returns an instance of Node's ClientRequest class. The callback function must have an `error` argument, which will be `null` if the request is successful, and a `response` argument, which will be an instance of Node's IncomingMessage class. The `query` and `headers` arguments should be plain old JavaScript objects, with the former being converted into a query string. The other arguments bar the last callback argument should be strings.
256
+ * The `createRequest()` function provides a means to make arbitrary requests.
257
+ * It takes `host`, `uri`, `query`, `method`, `headers` and `callback` arguments.
258
+ * It returns an instance of Node's ClientRequest class.
259
+ * The callback function must have an `error` argument, which will be `null` if the request is successful, and a `response` argument, which will be an instance of Node's IncomingMessage class.
260
+ * The `query` and `headers` arguments should be plain old JavaScript objects, with the former being converted into a query string.
261
+ * The other arguments bar the last callback argument should be strings.
234
262
 
235
- In the following example a GET request is made. Note that because the request body is empty, it is enough to call the request object's `end()` method in order to make the request. Note also that the response is piped directly to a file.
263
+ In the following example a GET request is made.
264
+ Note that because the request body is empty, it is enough to call the request object's `end()` method in order to make the request.
265
+ Note also that the response is piped directly to a file.
236
266
 
237
267
  ```
238
268
  const { createWriteStream } = require("fs");
@@ -257,7 +287,9 @@ const host = ...,
257
287
  request.end();
258
288
  ```
259
289
 
260
- In the following example the `queryStringFromQuery()` function from the HTTP utilities is used to encode the body of the request. Note that the `content-type` header is set explicitly. Note that the request body is piped directly from a file:
290
+ In the following example the `queryStringFromQuery()` function from the HTTP utilities is used to encode the body of the request.
291
+ Note that the `content-type` header is set explicitly.
292
+ Note that the request body is piped directly from a file:
261
293
 
262
294
  ```
263
295
  const { createReadStream } = require("fs");
@@ -417,7 +449,8 @@ const line = "${name}, aged ${age}.",
417
449
  - `renameEntry()`
418
450
  - `removeEntry()`
419
451
 
420
- An inglorious collection of functions which do no more than paper over some of Node's synchronous [native file system API](https://nodejs.org/api/fs.html) functions. All of the functions will throw native errors upon failure.
452
+ An inglorious collection of functions which do no more than paper over some of Node's synchronous [native file system API](https://nodejs.org/api/fs.html) functions.
453
+ All of the functions will throw native errors upon failure.
421
454
 
422
455
  * The `getEntryStats()` function returns an instance of the [fs.Stats](https://nodejs.org/api/fs.html#fs_class_fs_stats) class:
423
456
 
@@ -447,25 +480,31 @@ isDirectoryEmpty("root/etc"); // returns true if the directory is empty
447
480
  readDirectory("root/etc"); // returns the contents of the 'root/etc' directory
448
481
  ```
449
482
 
450
- * The `readFile()` function takes the file encoding as an optional second string argument. The default is `utf8`. It returns the content of the file upon success:
483
+ * The `readFile()` function takes the file encoding as an optional second string argument.
484
+ * The default is `utf8`.
485
+ * It returns the content of the file upon success:
451
486
 
452
487
  ```
453
488
  readFile("root/etc/init.conf"); // returns the content of the 'root/etc/init.conf' file
454
489
  ```
455
490
 
456
- * The `copyFile()` function takes as arguments the source and target file paths. It will overwrite an existing file without throwing an error. It does not return anything upon success:
491
+ * The `copyFile()` function takes as arguments the source and target file paths.
492
+ * It will overwrite an existing file without throwing an error.
493
+ * It does not return anything upon success:
457
494
 
458
495
  ```
459
496
  copyFile("root/etc/init.conf", "tmp/init.conf"); // copies the 'init.conf' file in the '/root/etc' folder to the '/tmp' folder
460
497
  ```
461
498
 
462
- * The `writeFile()` function takes the content of the file as a second string argument. It does not return anything upon success:
499
+ * The `writeFile()` function takes the content of the file as a second string argument.
500
+ * It does not return anything upon success:
463
501
 
464
502
  ```
465
503
  writeFile("root/etc/init.conf", ""); // writes '' to the 'root/etc/init.conf' file
466
504
  ```
467
505
 
468
- * The `appendToFile()` function takes the content to append file as a second string argument. It will create teh file if necessary and does not return anything upon success:
506
+ * The `appendToFile()` function takes the content to append file as a second string argument.
507
+ * It will create teh file if necessary and does not return anything upon success:
469
508
 
470
509
  ```
471
510
  appendToFile("root/etc/init.conf", ""); // appends '' to the 'root/etc/init.conf' file
@@ -477,7 +516,8 @@ appendToFile("root/etc/init.conf", ""); // appends '' to the 'root/etc/init.conf
477
516
  createDirectory("root/etc/init"); // Creates the 'root/etc/init' directory
478
517
  ```
479
518
 
480
- * The `createFile()` creates an empty file. It does not return anything upon success:
519
+ * The `createFile()` creates an empty file.
520
+ * It does not return anything upon success:
481
521
 
482
522
  ```
483
523
  createFile("root/etc/init.conf"); // writes '' to the 'root/etc/init.conf' file
@@ -503,7 +543,8 @@ Note that in the case of a directory, all of its sub-entries will be removed as
503
543
  renameFile("hosts", "host"); // Renames the 'hosts' file to 'host'
504
544
  ```
505
545
 
506
- Note that if the parent directory of the newly named file or directory does not exist then this function will fail. Instead use the `moveEntry()` function.
546
+ Note that if the parent directory of the newly named file or directory does not exist then this function will fail.
547
+ Instead use the `moveEntry()` function.
507
548
 
508
549
  ## Configuration utilities
509
550
 
@@ -521,7 +562,8 @@ const { logOptions } = rc;
521
562
  setLogOptions(logOptions);
522
563
  ```
523
564
 
524
- The default name for the file is `.rc` and it must be present in the current working directory. It must have the following format:
565
+ The default name for the file is `.rc` and it must be present in the current working directory.
566
+ It must have the following format:
525
567
 
526
568
  ```
527
569
  {
@@ -547,7 +589,9 @@ If neither of these checks are successful then it will return the first element
547
589
 
548
590
  Note that it will not try to assign the `name` property of the chosen environment to itself, because functions already have a `name` property.
549
591
 
550
- Before returning the JSON, it will search for uppercase strings. If such a string is the name of an environment variable, it will be replaced by the environment variable's value. This means that you can choose to keep sensitive information out of the runtime configuration and therefore, for instance, safely commit it to the repository.
592
+ Before returning the JSON, it will search for uppercase strings.
593
+ If such a string is the name of an environment variable, it will be replaced by the environment variable's value.
594
+ This means that you can choose to keep sensitive information out of the runtime configuration and therefore, for instance, safely commit it to the repository.
551
595
 
552
596
  You can change the base extension of the file that is parsed, that is the part of the extension between the leading dot and `rc`, by making use of the `setRCBaseExtension()` function:
553
597
 
@@ -561,7 +605,10 @@ rc(); // Provides the first environment in the '.defaultrc' file
561
605
 
562
606
  Note that the `rc()` function can be included in any file but only needs to be called once. But be careful that it is called before it is ever destructured.
563
607
 
564
- Aside from the aforementioned `setRCBaseExtension()` functions, the `checkRCFileExists()`, `createVacuousRCFile()`, `readRCFile()` and `writeRCFile()` functions do as their names suggest. The `updateRCFile()` function, if passed a plain old JavaScript object as the first argument, will add the properties therein, overwriting any existing properties. Properties to be removed can be given as further arguments. If you do not want to add as well as remove properties, set the first argument to a falsey value.
608
+ Aside from the aforementioned `setRCBaseExtension()` functions, the `checkRCFileExists()`, `createVacuousRCFile()`, `readRCFile()` and `writeRCFile()` functions do as their names suggest.
609
+ The `updateRCFile()` function, if passed a plain old JavaScript object as the first argument, will add the properties therein, overwriting any existing properties.
610
+ Properties to be removed can be given as further arguments.
611
+ If you do not want to add as well as remove properties, set the first argument to a falsey value.
565
612
 
566
613
  ```
567
614
  const { readRCFile, writeRCFile, updateRCFile, checkRCFileExists, createVacuousRCFile } = rc;
@@ -594,7 +641,8 @@ updateRCFile(null, "example"); // Updates the rc file, removing the 'example' p
594
641
  - `pathWithoutBottommostNameFromPath()`
595
642
  - `pathWithoutTopmostDirectoryNameFromPath()`
596
643
 
597
- These functions manipulate or query strings that represent file and directory paths. Note that only forward slash `/` delimiters are supported. Trailing delimiters are not needed, but tolerated.
644
+ These functions manipulate or query strings that represent file and directory paths.
645
+ Note that only forward slash `/` delimiters are supported. Trailing delimiters are not needed, but tolerated.
598
646
 
599
647
  * The `isPathName()` function returns `true` if the string argument contains no `/` delimiters apart from the first and last characters:
600
648
 
@@ -646,9 +694,11 @@ isTopmostNameInAbsolutePath("root", "/root/etc"); // returns false
646
694
  isTopmostNameInAbsolutePath("etc", "/root/etc"); // returns false
647
695
  ```
648
696
 
649
- Note that the function assumes that the first argument is a topmost name and that the second argument is an abolute path. It does not check, it simply compares the two arguments with a single regex.
697
+ Note that the function assumes that the first argument is a topmost name and that the second argument is an abolute path.
698
+ It does not check, it simply compares the two arguments with a single regex.
650
699
 
651
- * The `combinePaths()` function will combine the first string argument with the second string argument by successively removing the bottommost directory name of the former for each topmost parent directory `..` signifier it finds in the latter. Current directory `.` signifiers are also removed:
700
+ * The `combinePaths()` function will combine the first string argument with the second string argument by successively removing the bottommost directory name of the former for each topmost parent directory `..` signifier it finds in the latter.
701
+ * Current directory `.` signifiers are also removed:
652
702
 
653
703
  ```
654
704
  combinePaths("etc/", "./init"); // returns 'etc/init'
@@ -668,7 +718,8 @@ concatenatePaths("root/", "etc/"); // returns 'root/etc/'
668
718
 
669
719
  Note that the function assumes that the second argument is a relative name or path although without a leading current directory `.` or parent directory `..` signifier.
670
720
 
671
- * The `bottommostNameFromPath()`, `topmostDirectoryPathFromPath()`, `topmostDirectoryNameFromPath()`, `pathWithoutBottommostNameFromPath()` and `pathWithoutTopmostDirectoryNameFromPath()` functions work as their names suggest. Each expects there to be at least one delimiter, returning `null` otherwise:
721
+ * The `bottommostNameFromPath()`, `topmostDirectoryPathFromPath()`, `topmostDirectoryNameFromPath()`, `pathWithoutBottommostNameFromPath()` and `pathWithoutTopmostDirectoryNameFromPath()` functions work as their names suggest.
722
+ * Each expects there to be at least one delimiter, returning `null` otherwise:
672
723
 
673
724
  ```
674
725
  bottommostNameFromPath("../etc"); // returns 'etc'
@@ -739,18 +790,24 @@ pathWithoutTopmostDirectoryNameFromPath("root/etc/init.conf"); // returns 'etc/i
739
790
  - `backwardsReduce()`
740
791
  - `forwardsForEach()`
741
792
  - `backwardsForEach()`
793
+ - `forwardsFindIndex()`
794
+ - `backwardsFindIndex()`
742
795
 
743
796
  Note that none of these functions take or pass on a `thisArg` argument when they might otherwise have done. Use `bind()`.
744
797
 
745
- * The functions `first()` through to `last()` return the requisite element of the array argument, if passed an array of at least the required length. If the array is not long enough they return `undefined`.
798
+ * The functions `first()` through to `last()` return the requisite element of the array argument, if passed an array of at least the required length.
799
+ If the array is not long enough they return `undefined`.
746
800
 
747
- * The `head()` function returns an array containing the first element of its array argument whilst the `tail()` function returns an array containing all but the first element of its array argument. The `back()` function returns an array containing hte last element of its array argument whilst the `front()` function returns an array returning all but the last element of its array argument.
801
+ * The `head()` function returns an array containing the first element of its array argument whilst the `tail()` function returns an array containing all but the first element of its array argument.
802
+
803
+ * The `back()` function returns an array containing hte last element of its array argument whilst the `front()` function returns an array returning all but the last element of its array argument.
748
804
 
749
805
  * The `push()` function is similar to its native counterpart but will push an array rather than a single element.
750
806
 
751
807
  * The `unshift()` function is similar to its native counterpart but will unshift an array rather than a single element.
752
808
 
753
- * The `concat()` function is similar to its native counterpart, however it alters the first array argument *in place*. Like its native counterpart it will also take a single element as the second argument and convert it to an array.
809
+ * The `concat()` function is similar to its native counterpart, however it alters the first array argument *in place*.
810
+ Like its native counterpart it will also take a single element as the second argument and convert it to an array.
754
811
 
755
812
  ```
756
813
  concat([1, 2, 3], 4); // the array argument becomes [1, 2, 3, 4]
@@ -762,7 +819,8 @@ concat([1, 2, 3], 4); // the array argument becomes [1, 2, 3, 4]
762
819
  clear([1, 2, 3]); // the array argument becomes []
763
820
  ```
764
821
 
765
- * The `copy()` function copies the second array argument over the top of the first array argument, in other words it replaces each element of the first array argument with the corresponding element in the second array argument. If there are more elements in the second array argument that the first, the first is lengthened:
822
+ * The `copy()` function copies the second array argument over the top of the first array argument, in other words it replaces each element of the first array argument with the corresponding element in the second array argument.
823
+ If there are more elements in the second array argument that the first, the first is lengthened:
766
824
 
767
825
  ```
768
826
  copy([1, 2, 3], [4, 5, 6, 7]); // the first array argument becomes [4, 5, 6, 7]
@@ -774,7 +832,8 @@ copy([1, 2, 3], [4, 5, 6, 7]); // the first array argument becomes [4, 5, 6, 7]
774
832
  merge([1, 2, 3], [4, 5, 6, 7]); // the first array argument becomes [1, 2, 3, 4, 5, 6, 7]
775
833
  ```
776
834
 
777
- * The `match()` function compares the first and second array arguments in order. If they are of the same length and the callback argument supplied returns a truthy value when invoked with each pair of elements then it returns true:
835
+ * The `match()` function compares the first and second array arguments in order.
836
+ If they are of the same length and the callback argument supplied returns a truthy value when invoked with each pair of elements then it returns true:
778
837
 
779
838
  ```
780
839
  match([1, 2, 3], [-1, -2, -3], (valueA, valueB) => (valueA === -valueB)); // returns true
@@ -796,15 +855,21 @@ correlate([1, 2, 3], [-4, -2, -3, -1], (valueA, valueB) => (valueA === -valueB))
796
855
 
797
856
  Again note that pairs of elements can match once and once only.
798
857
 
799
- * The `resolve()` function repeatedly iterates over the elements of the first array argument, removing them and adding them to the second array argument if the callback function returns a truthy value. If the callback function does not return a truthy value for any of the elements of the first array argument or the length of the first array is zero, it terminates.
858
+ * The `resolve()` function repeatedly iterates over the elements of the first array argument, removing them and adding them to the second array argument if the callback function returns a truthy value.
859
+ If the callback function does not return a truthy value for any of the elements of the first array argument or the length of the first array is zero, it terminates.
800
860
 
801
861
  ```
802
862
  resolve([1, 2, 3], [], (value) => true); // moves the elemnts of the first array argument into the second array argument and returns true
803
863
  ```
804
864
 
805
- The above code snippet is perhaps not very helpful so it is worth explaining this function's utility in the context of a use case. Suppose a compiler has to compile all the files in a given directory. There are inter-dependencies between the files, however, so some files will not compile until their dependents have compiled. If there are orderings of files that allow them to all be compiled, this function will find one of them by trial and error, so to speak. The second array argument will contain the elements according to this ordering.
865
+ The above code snippet is perhaps not very helpful so it is worth explaining this function's utility in the context of a use case.
866
+ Suppose a compiler has to compile all the files in a given directory.
867
+ There are inter-dependencies between the files, however, so some files will not compile until their dependents have compiled.
868
+ If there are orderings of files that allow them to all be compiled, this function will find one of them by trial and error, so to speak.
869
+ The second array argument will contain the elements according to this ordering.
806
870
 
807
- The first array argument is left untouched whether or not the function succeeds. The second array argument may contain elements if it has only been partially successful, however.
871
+ The first array argument is left untouched whether or not the function succeeds.
872
+ The second array argument may contain elements if it has only been partially successful, however.
808
873
 
809
874
  * The `find()` function is like its native counterpart, however it returns an array of all the elements for which the callback function returns a truthy value, rather than just the first:
810
875
 
@@ -818,13 +883,17 @@ find([1, 2, -1, -2], (element, index) => (element > 0)); // returns [1, 2]
818
883
  replace([1, 0, -2], 3, (element, index) => (element === 0)); // the array argument becomes [1, 3, -2]
819
884
  ```
820
885
 
821
- * The `splice()` function works in a similar vein to its native counterpart, however it takes an array as the optional fourth argument rather than a series of elements from the fourth argument onwards. It mutates the first array argument and returns an array of the elements that have been deleted:
886
+ * The `splice()` function works in a similar vein to its native counterpart, however it takes an array as the optional fourth argument rather than a series of elements from the fourth argument onwards.
887
+ It mutates the first array argument and returns an array of the elements that have been deleted:
822
888
 
823
889
  ```
824
890
  splice([1, 2, 3], 1, 2, [4, 5]); // the first array argument becomes [1, 4, 5]
825
891
  ```
826
892
 
827
- * The `filter()` function is like its native counterpart, however it filters the first array argument *in place*. The second argument should be a callback function that will be invoked for each element of the array. If it does not return a truthy value, the corresponding element will be deleted. The deleted elements are returned.
893
+ * The `filter()` function is like its native counterpart, however it filters the first array argument *in place*.
894
+ The second argument should be a callback function that will be invoked for each element of the array.
895
+ If it does not return a truthy value, the corresponding element will be deleted.
896
+ The deleted elements are returned.
828
897
 
829
898
  ```
830
899
  filter([1, 2, -2], (element, index) => (element > 0)); // returns [-2] and the array argument becomes [1, 2]
@@ -878,7 +947,9 @@ augment([1, 2, 3], [-1, 4, -2, 5], (element, index) => (element > 0)); // the ar
878
947
  separate([1, -1, -2, 2, 3, -3], [], [], (element, index) => {(element > 0)); // the second and third array arguments become [1, 2, 3] and [-1, -2, 3], respectively.
879
948
  ```
880
949
 
881
- The `forwardsXXX()` and `backwardsXXX()`functions do as their names suggest. The `fowardsXXX()` function take an array for their first argument but otherwise behave identically to their native counterparts. The `backwardsXXX()` functions behave similarly, only backwards.
950
+ The `forwardsXXX()` and `backwardsXXX()`functions do as their names suggest.
951
+ The `fowardsXXX()` functions take an array for their first argument but otherwise behave identically to their native counterparts.
952
+ The `backwardsXXX()` functions behave similarly, only backwards.
882
953
 
883
954
  ## HTTP utilities
884
955
 
@@ -892,7 +963,9 @@ The `forwardsXXX()` and `backwardsXXX()`functions do as their names suggest. The
892
963
 
893
964
  Helper functions to manipulate HTTP headers and URLs, build query strings and so on.
894
965
 
895
- * The `overwrite()` function takes a plain old JavaScript object `headers` argument together with `name` and `value` string arguments. If the corresponding property of the `headers` object exists then it is replaced with the `value` value. This function's utility lies in the fact that the name comparisons are case insensitive.
966
+ * The `overwrite()` function takes a plain old JavaScript object `headers` argument together with `name` and `value` string arguments.
967
+ If the corresponding property of the `headers` object exists then it is replaced with the `value` value.
968
+ This function's utility lies in the fact that the name comparisons are case insensitive.
896
969
 
897
970
  ```
898
971
  const headers = {
@@ -902,7 +975,9 @@ const headers = {
902
975
  overwrite(headers, "content-type", "text/html"); // headers["Content-Type"] = "text/html"
903
976
  ```
904
977
 
905
- * The `underwrite()` function takes a plain old JavaScript object `headers` argument together with `name` and `value` string arguments. If the corresponding property of the `headers` object does not exist then it is created with the `value` value. This function's utility lies in the fact that the name comparisons are case insensitive.
978
+ * The `underwrite()` function takes a plain old JavaScript object `headers` argument together with `name` and `value` string arguments.
979
+ If the corresponding property of the `headers` object does not exist then it is created with the `value` value.
980
+ This function's utility lies in the fact that the name comparisons are case insensitive.
906
981
 
907
982
  ```
908
983
  const headers = {
@@ -940,7 +1015,8 @@ secureFromHost("https://site.com"); // returns true
940
1015
  hostnameFromHost("http://site.com"); // returns "site.com"
941
1016
  ```
942
1017
 
943
- * The `queryStringFromQuery()` function takes a plain old JavaScript object `query` argument and returns the corresponding URL encoded query string. It uses the [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) to encode the names and values
1018
+ * The `queryStringFromQuery()` function takes a plain old JavaScript object `query` argument and returns the corresponding URL encoded query string.
1019
+ It uses the [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) to encode the names and values
944
1020
 
945
1021
  ```
946
1022
  const query = {
@@ -950,7 +1026,8 @@ const query = {
950
1026
  queryStringFromQuery(query); // returns John%20Doe
951
1027
  ```
952
1028
 
953
- * The `urlFromHostURIAndQuery()` function takes `host` and `uri` string arguments together with a `query` plain old JavaScript object argument. It creates a query string from the `query` object and concatenates this with the two other arguments in oder to create a fully qualified HTTP URL.
1029
+ * The `urlFromHostURIAndQuery()` function takes `host` and `uri` string arguments together with a `query` plain old JavaScript object argument.
1030
+ It creates a query string from the `query` object and concatenates this with the two other arguments in oder to create a fully qualified HTTP URL.
954
1031
 
955
1032
  ```
956
1033
  const host = "https://site.com",
@@ -971,9 +1048,11 @@ Ideally the `host` argument should not include a trailing forward slash whereas
971
1048
  - `indexOf()`
972
1049
  - `substring()`
973
1050
 
974
- String functions with support for Unicode. Specifically, characters in Unicode astral plains are counted twice in native string functions and methods whereas these functions effectively count astral Unicode characters only once.
1051
+ String functions with support for Unicode.
1052
+ Specifically, characters in Unicode astral plains are counted twice in native string functions and methods whereas these functions effectively count astral Unicode characters only once.
975
1053
 
976
- * The `strlen()` function takes a single `string` argument. It works in much the same way as the `length` property of the `String` prototype, however it is Unicode safe:
1054
+ * The `strlen()` function takes a single `string` argument.
1055
+ It works in much the same way as the `length` property of the `String` prototype, however it is Unicode safe:
977
1056
 
978
1057
  ```
979
1058
  "𝔸𝔹C".length = 5 // The 𝔹 and C characters are in an astral plane and count as two each.
@@ -982,7 +1061,10 @@ strlen("𝔸𝔹C") = 3 // The string is converted to an array whose length is 3
982
1061
 
983
1062
  ```
984
1063
 
985
- * The `strcmp` function takes `stringA` and `stringB` arguments. It compares them character by character in order to find the lexicographically lesser of the two. Its return value is the difference between the code points of the first differing characters, with the code point of either string given as zero if it is empty. Some examples should clarify:
1064
+ * The `strcmp` function takes `stringA` and `stringB` arguments.
1065
+ It compares them character by character in order to find the lexicographically lesser of the two.
1066
+ Its return value is the difference between the code points of the first differing characters, with the code point of either string given as zero if it is empty.
1067
+ Some examples should clarify:
986
1068
 
987
1069
  ```
988
1070
  strcmp("", "") = 0;
@@ -1012,7 +1094,8 @@ indexOf("𝔸b", "b"); // Returns 1.
1012
1094
 
1013
1095
  In the above example the aforementioned native method would return 2.
1014
1096
 
1015
- * The `substring()` function takes `string` and `start` arguments and an optional `end` argument. It works in much the same way as the `substring()` method of the `String` prototype, however it is Unicode safe:
1097
+ * The `substring()` function takes `string` and `start` arguments and an optional `end` argument.
1098
+ It works in much the same way as the `substring()` method of the `String` prototype, however it is Unicode safe:
1016
1099
 
1017
1100
  ```
1018
1101
  "𝔸𝔹C".substring(3) = "C" // The 𝔹 character is in an astral plane and counts as two.
@@ -1026,7 +1109,8 @@ Note the native `substring()` method can be particularly egregious because the `
1026
1109
 
1027
1110
  - `migrate()`
1028
1111
 
1029
- A single `migrate()` function to handle the migration of JSON files with a required `version` entry. This function can be used in conjunction with the configuration utilities but does not have to be.
1112
+ A single `migrate()` function to handle the migration of JSON files with a required `version` entry.
1113
+ This function can be used in conjunction with the configuration utilities but does not have to be.
1030
1114
 
1031
1115
  * The `migrate` function takes `json`, `migrationMap` and `latestVersion` arguments. Perhaps the easiest way to demonstrate its use is by way of an extensive example.
1032
1116
 
@@ -1074,7 +1158,8 @@ function migrateConfigurationFile() {
1074
1158
  }
1075
1159
  ```
1076
1160
 
1077
- Note carefully the matching of the keys to their corresponding values. Each key matches the version that the `migrate()` function finds in the JSON. It therefore must apply the requisite migration function to migrate the JSON to the next version.
1161
+ Note carefully the matching of the keys to their corresponding values. Each key matches the version that the `migrate()` function finds in the JSON.
1162
+ It therefore must apply the requisite migration function to migrate the JSON to the next version.
1078
1163
 
1079
1164
  Lastly, the migration function must have the prescribed signature and return the migrated JSON. Again an example will suffice:
1080
1165
 
@@ -1092,7 +1177,8 @@ function migrateConfigurationToVersion_2_0(configuration) {
1092
1177
  }
1093
1178
  ```
1094
1179
 
1095
- In this admittedly somewhat trivial example, all the migration function does is to update the version number. Exactly how the JSON otherwise changes is immaterial but the version number must be updated in this way otherwise the `migrate()` function will loop indefinitely.
1180
+ In this admittedly somewhat trivial example, all the migration function does is to update the version number.
1181
+ Exactly how the JSON otherwise changes is immaterial but the version number must be updated in this way otherwise the `migrate()` function will loop indefinitely.
1096
1182
 
1097
1183
  ## Asynchronous utilities
1098
1184
 
@@ -1102,9 +1188,13 @@ In this admittedly somewhat trivial example, all the migration function does is
1102
1188
  - `eventually()`
1103
1189
  - `repeatedly()`
1104
1190
 
1105
- These functions generally take either an operation or an array of operations, an operation being a function that mutates a context rather than returning a value. They also take a `done()` function and an optional `context` argument. They all pass a `next()` function to the operations followed by the `done()` function, the `context` and then an `index` argument. Operations can call the `done()` function instead of the `next()` function in order to terminate early.
1191
+ These functions generally take either an operation or an array of operations, an operation being a function that mutates a context rather than returning a value.
1192
+ They also take a `done()` function and an optional `context` argument.
1193
+ They all pass a `next()` function to the operations followed by the `done()` function, the `context` and then an `index` argument. Operations can call the `done()` function instead of the `next()` function in order to terminate early.
1106
1194
 
1107
- * The `whilst()` function takes a single operation, which it calls each time the operation invokes the given `next()` function or until the operation invokes the given `done()` function. The operation can also force termination by returning a truthy value, in which case it must *not* call the given `next()` or `done()` functions. In the example below the operation will be executed ten times:
1195
+ * The `whilst()` function takes a single operation, which it calls each time the operation invokes the given `next()` function or until the operation invokes the given `done()` function.
1196
+ The operation can also force termination by returning a truthy value, in which case it must *not* call the given `next()` or `done()` functions.
1197
+ In the example below the operation will be executed ten times:
1108
1198
 
1109
1199
  ```
1110
1200
  const context = {}; ///
@@ -1126,7 +1216,9 @@ whilst(operation, () => {
1126
1216
  }, context);
1127
1217
  ```
1128
1218
 
1129
- * The `forEach()` function takes an array as the first argument followed by a single operation, which it calls for each element of the array unless the operation invokes the given `done()` function. If the `done()` function is never invoked by the operation, it is called once each of the array elements has been passed to the operation, provided the operationinvokes the given `next ()` function each time. In the example below the operation will be executed four times:
1219
+ * The `forEach()` function takes an array as the first argument followed by a single operation, which it calls for each element of the array unless the operation invokes the given `done()` function.
1220
+ If the `done()` function is never invoked by the operation, it is called once each of the array elements has been passed to the operation, provided the operation invokes the given `next ()` function each time.
1221
+ In the example below the operation will be executed four times:
1130
1222
 
1131
1223
  ```
1132
1224
  const context = {};
@@ -1150,7 +1242,9 @@ forEach(array, operation, () => {
1150
1242
  }, context);
1151
1243
  ```
1152
1244
 
1153
- * The `sequence()` function takes an array of operations, which it calls in turn unless the operation invokes the given `done()` function. If the `done()` function is never invoked by a operation, it is called once each of the operations have been called, provided each operation invokes the given `next ()` function. In the example below each of the operations bar the last is executed:
1245
+ * The `sequence()` function takes an array of operations, which it calls in turn unless the operation invokes the given `done()` function.
1246
+ If the `done()` function is never invoked by a operation, it is called once each of the operations have been called, provided each operation invokes the given `next ()` function.
1247
+ In the example below each of the operations bar the last is executed:
1154
1248
 
1155
1249
  ```
1156
1250
  const context = {};
@@ -1171,7 +1265,9 @@ sequence(operations, () => {
1171
1265
  }, context);
1172
1266
  ```
1173
1267
 
1174
- * The `eventually()` function takes an array of operations, each of which it calls immediately without waiting for the operations to invoke the given `next()` functions. When each of the operations has invoked the given `next()` function, it will call the `done()` function. Note that in this case invoking the `done()` function from within a operation will not halt the execution of other operations, it is passed as an argument only for the sake of convention. In the example below each of the operations is executed:
1268
+ * The `eventually()` function takes an array of operations, each of which it calls immediately without waiting for the operations to invoke the given `next()` functions. When each of the operations has invoked the given `next()` function, it will call the `done()` function.
1269
+ Note that in this case invoking the `done()` function from within a operation will not halt the execution of other operations, it is passed as an argument only for the sake of convention.
1270
+ In the example below each of the operations is executed:
1175
1271
 
1176
1272
  ```
1177
1273
  const context = {};
@@ -1189,7 +1285,9 @@ eventually(operations, () => {
1189
1285
  /// done
1190
1286
  }, context);
1191
1287
  ```
1192
- * The `repeatedly()` function takes a single operation and a `length` argument, immediately calling the operation a `length` number of times without waiting for it to invoke the given `next()` function each time. When the operation has invoked the given `next()` function a `length` number of times, it will call the `done()` function. Note that in this case invoking the `done()` function from within the operation will not halt its execution the requisite number of times, it is passed as an argument only for the sake of convention. In the example below the operation is executed ten times:
1288
+ * The `repeatedly()` function takes a single operation and a `length` argument, immediately calling the operation a `length` number of times without waiting for it to invoke the given `next()` function each time. When the operation has invoked the given `next()` function a `length` number of times, it will call the `done()` function.
1289
+ Note that in this case invoking the `done()` function from within the operation will not halt its execution the requisite number of times, it is passed as an argument only for the sake of convention.
1290
+ In the example below the operation is executed ten times:
1193
1291
 
1194
1292
  ```
1195
1293
  const context = {};
@@ -1209,7 +1307,8 @@ repeatedly(operation, length, () => {
1209
1307
 
1210
1308
  ## Building
1211
1309
 
1212
- Automation is done with [npm scripts](https://docs.npmjs.com/misc/scripts), have a look at the `package.json` file. The pertinent commands are:
1310
+ Automation is done with [npm scripts](https://docs.npmjs.com/misc/scripts), have a look at the `package.json` file.
1311
+ The pertinent commands are:
1213
1312
 
1214
1313
  npm run build-debug
1215
1314
  npm run watch-debug