UNPKG

11 kBMarkdownView Raw
1<div align="center">
2
3### *Zero-dependency collection of tools aiming to speed up modern JavaScript development.*
4
5<br>
6
7![Version image](https://badgen.net/badge/npm/2.2.0/green?icon=npm)
8
9[![install size](https://packagephobia.com/badge?p=@applicvision/js-toolbox@latest)](https://packagephobia.com/result?p=@applicvision/js-toolbox@latest)
10
11```console
12> npm install @applicvision/js-toolbox
13```
14
15</div>
16
17<br>
18
19
20## Toolbox contents
21
22 - [Tests](#tests)
23 - [Auto reload](#auto-reload)
24 - [Ayay](#ayay)
25 - [IzzaDate](#izzadate)
26 - [Argument Parser](#argument-parser)
27 - [Terminal Style](#terminal-style)
28
29<br>
30<br>
31
32# Tests
33
34Write tests with EcmaScript modules syntax, and run them both in browser and in Node, without any build step. Compose your tests in suites using `describe`, and declare test units with `test` or `it`:
35
36```javascript
37// test.js
38import {describe, it} from '@applicvision/js-toolbox/test'
39import assert from 'node:assert/strict'
40
41describe('My suite', () => {
42 it('test', () => {
43 assert.equal(1 + 1, 2)
44 })
45})
46```
47
48A bin called `testa` (Swedish for 'test' in imperative form) is exported which runs the test. So either put `test: testa` in your package.json script section, and call:
49```
50npm test
51```
52
53Or even shorter, just call with npx:
54
55```
56npx testa
57```
58
59In your `package.json` you can configure which files will be picked up by the test runner.
60```json
61"config": {
62 "testa": {
63 "endsWith": ".test.js"
64 }
65}
66```
67By default, files ending with `.test.js` will be searched for from the project directory, but you can specify files and folders as argument to limit the search: `testa unit integration extra.test.js`.
68
69Passing `--help` will print the usage information:
70
71```
72Options:
73 -f, --filter Specify a regex to only run matching tests and describes.
74 -l, --logger Specify a logger for the test. Available: animated, simple. Default: animated
75 -m, --mode Specify mode, node or browser. Default node.
76 -w, --watch In browser mode, reload on file changes in specified directory.
77 -p, --port In browser mode, select the port to run the server on. Default 3000.
78 --timeout Set general time limit for tests. Default 4s.
79 --bail Exit immediately on first test failure.
80 --only Run only tests marked with only.
81 --notify Show MacOS notification (osascript)
82 -h, --help Show this message and exit.
83```
84
85## Browser mode
86Going back to the start of the test module example
87```javascript
88import { describe, test } from '@applicvision/js-toolbox/test'
89import assert from 'node:assert/strict'
90```
91one might wonder how this code will run in the browser, without any compiling, transpiling, translation, build steps or anything.
92
93The answer to that is two fairly new features for EcmaScript modules. The first is in the browser, and is called importmaps, which is available in recent versions of the major web browsers. See more at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap.
94
95The other is on the Node side, and is called `import.meta.resolve`. More info here: https://nodejs.org/dist/latest-v20.x/docs/api/esm.html#importmetaresolvespecifier.
96
97So the first line in the example above is resolved to the correct file in node_modules, when the browser requests the module.
98
99And the second line, `import node:assert/strict`, is intercepted and resolves a browser compatible implementation of `node:assert/strict`.
100
101A separate bin called `browser-test` is exposed. It simply calls the testrunner with test mode set to browser.
102
103The server for browser testing is run with http by default, but can also be run with https. To set this up, please create a `key.pem` (private key) and `cert.pem` (certificate), in any directory, and set the directory location to an environment variable called `JS_TOOLBOX_CERT`.
104
105Once the server is started, default port is 3000, simply visit the page in the browser to run the tests.
106
107Query parameters can be used to configure the tests. Available query parameters are:
108* `only` – run only tests marked with only
109* `filter=<regex>` – Run tests matching filter.
110* `expand` – Keep the test suites expanded when finished
111
112Two examples:
113```bash
114'https://localhost:3000/?only'
115#run only tests marked with .only
116
117'https://localhost:3000/?filter=sum|random&filter=ayay'
118#run only tests matching /sum|random/ and /ayay/
119```
120<br>
121
122# Auto reload
123
124Auto reload is a tool to make the browser reload when files are changed. Start it with the exported bin, `autoreload`.
125In package json, add a script row:
126```
127autoreload: autoreload src
128```
129And then call
130```
131npm run autoreload
132```
133Or with npx:
134```
135npx autoreload src
136```
137
138This starts the file watcher and the server. The default port is 3333, but this can be configured with option `--port`. The server can also be run with https. To set up this, please create a `key.pem` (private key) and `cert.pem` (certificate), in any directory, and set the directory location to an environment variable called `JS_TOOLBOX_CERT`, or pass the directory location with the option `--certificate`.
139
140Example:
141```
142npx autoreload --certificate ~/certificates/localhost
143```
144
145Then in your web application, during development, import the client script, and call start:
146```html
147<script type="module">
148 import { start } from 'https://localhost:3333/autoreload.js'
149 start()
150</script>
151```
152
153A little indicator will appear in the bottom right corner. If the indicator is green, it means autoreload is active, and file changes will trigger page reload. If it turns red, it means it lost connection to the server. It will automatically try to reconnect if it loses connection, and if connection is reestablished, the indicator color will return to green.
154
155The file watcher can also be used as a standalone bin:
156```
157npx filewatcher .
158```
159
160Then it will emit to standard out when files change, and another process could be piped to it to handle file changes. The auto reload functionality is built that way.
161
162<br>
163
164# Ayay
165
166A subclass of the native Array. The aim is to extend Array with immutable methods. Create instances of Ayay using the constructor, or any of the static factory methods (which are just the same as those of Array):
167
168```javascript
169import Ayay from '@applicvision/js-toolbox/Ayay'
170
171const anArray = new Ayay()
172// or
173const anArray = Ayay.of(1, 2, 3)
174// or
175const anotherArray = Ayay.from([1, 2, 3, 4])
176```
177
178There are also two other static methods for constructing instances:
179
180`fromPrettyJoined`, `seedWith`
181
182Available prototype methods:
183
184`arrayByDroppingLastItem`, `arrayByInsertingItem`, `arrayByMoving`, `arrayByRemovingItemAtIndex`, `arrayByReplacingItemAtIndex`, `arrayBySwappingItems`, `arraySortedBy`, `asyncFilter`, `average`, `chunksOf`, `compactMap`, `findLast`, `findLastIndex`, `get first`, `groupBy`, `indices`, `isEmpty`, `isShallowIdenticalWith`, `iterateWhile`, `get last`, `get lastIndex`, `mapWhile`, `omitInObject`, `permutations`, `pickInObject`, `get pipe`, `prettyJoin`, `randomIndex`, `randomItem`, `reduceWhile`, `reversedArray`, `sampleOfSize`, `shuffledArray`, `sumItems`, `sumItemsWhile`, `toVanilla`, `transpose`, `uniqueItems`, `useAsKeyPathIn`, `get vanilla`
185
186Methods have been named in order to hopefully make them self explanatory. But additional documentation and examples are available in the TypeScript definitions, and will show in your editor.
187
188One example:
189```javascript
190const numberArray = Ayay.of(1, 2, 3, 4, 5, 6)
191
192numberArray
193 .arrayByDroppingLastItem()
194 .average() // 3
195
196// original array not modified
197numberArray // [1, 2, 3, 4, 5, 6]
198
199```
200
201<br>
202
203# IzzaDate
204
205IzzaDate is a small subclass of the native Date class. It enables easier manipulation, and some immutable operations on Date objects, as well as a few methods for date comparison.
206
207Available methods:
208
209`add`, `components`, `copy`, `dateByAdding`, `dateBySetting`, `dateBySubtracting`, `daysSince`, `daysUntil`, `get`, `isEarlierInTheDay`, `isLaterInTheDay`, `isSameTimeOfDay`, `set`, `subtract`
210
211Documentation is available in TypeScript definition.
212
213One example:
214```javascript
215import IzzaDate, { DAY } from '@applicivions/js-toolbox/izza-date'
216const now = new IzzaDate()
217const tomorrow = now.dateByAdding(1, DAY)
218now.daysUntil(tomorrow) // 1
219```
220<br>
221
222# Terminal Style
223
224Simple utility to get colored output in the terminal.
225
226```javascript
227import style from '@applicvision/js-toolbox/style'
228
229console.log(
230 style.cyan('This text is Cyan'),
231 style.bold.red('This text is red and bold')
232)
233```
234
235Available styles are those defined in `util.inspect.colors`, please see https://nodejs.org/api/util.html#foreground-colors for reference.
236
237The default export is a function, with the following properties. Each property returns the style function with that text modifier activated.
238
239`blue`, `bold`, `cyan`, `dim`, `gray`, `green`, `italic`, `red`, `underline`
240
241The modifiers are chainable to combine styles:
242
243```javascript
244style.green.bold.italic.underline('Hello')
245```
246
247And can be nested
248```javascript
249style.blue(`blue ${style.bold('bold and blue')} blue`)
250```
251
252To pass custom style string, use `.custom`:
253
254```javascript
255console.log(style.custom('bgRed', 'bold')('Hello Red background'))
256```
257<br>
258
259# Argument Parser
260Argument parser is a simple utility to configure a command line tool. Specify which options and flags a program accepts. The parser will parse the arguments sent (by default `process.argv.slice(2)`).
261
262Given this
263```javascript
264// program.js
265import {parseArguments} from '@applicvision/js-toolbox/args'
266const parsed = parseArguments
267 .option('message', { description: 'Specify a message' })
268 .flag('flag', { description: 'A boolean option'})
269 .option('option', { description: 'Another good option' })
270 .help('Welcome to the program')
271 .parse()
272```
273
274When invoked like this
275```
276node program.js --option=value1 --option value2 --flag -mhello -- arg1 arg2
277```
278
279The argument parser will return this:
280```
281{
282 options: { option: [ 'value1', 'value2' ], flag: true, message: 'hello' },
283 args: [ 'arg1', 'arg2' ]
284}
285```
286
287If `--help` or `-h` is passed, the parser will return an object with `help` as the only property. This help can be logged to display a generated message to the user:
288```
289Welcome to the program
290
291Options:
292 -m, --message Specify a message
293 -f, --flag A boolean option
294 -o, --option Another good option
295 -h, --help Show this message and exit.
296```
297
298if an unknown option is passed, or if a value is not correctly passed to an option, the parser will throw an error, with a message that can be logged to the user:
299
300```
301node program.js --missing-option=value1
302```
303
304```
305Error Unknown option 'missing-option'
306
307Available options:
308 -m, --message Specify a message
309 -f, --flag A boolean option
310 -o, --option Another good option
311 -h, --help Show this message and exit.
312
313```
314
315
316<div align="center">
317<br>
318
319*Passionately developed by ApplicVision*
320
321<br>
322
323[![ApplicVision logo](https://applicvision.com/img/applicvision.png)](https://applicvision.com)
324
325</div>