open-index/open-npm huggingface dataset:
npm package: @giancarl021/type-inference
Description: Infer JavaScript primitive types from a string
Author: Giancarlo Fontela da Luz
Latest version: 1.0.1

# type-inference

Infer JavaScript primtive types from a string value

## Why?

A separate package for simple primitive type inference allows the re-use of the code for more complex applications.

## Documentation and Source-Code

The full documentation and source code of this package can be found [here](https://github.com/Giancarl021/type-inference).
npm package: @giancosta86/beatrice
Description: Simplified text-to-speech for the browser
Author: Gianluca Costa
Latest version: 1.0.2

# beatrice

_Simplified text-to-speech for the browser_

![GitHub CI](https://github.com/giancosta86/beatrice/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fbeatrice.svg)](https://badge.fury.io/js/@giancosta86%2Fbeatrice)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

**beatrice** is a minimalist **TypeScript** library focusing on text-to-speech (TTS) within the browser.

## Installation

The package on NPM is:

> @giancosta86/beatrice

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

### Retrieving a voice

The very first step consists in retrieving a suitable voice for your target language:

```typescript
const mandarinVoice = findVoice(
  //eSpeak on Linux
  voice => voice.name == "Chinese (Mandarin)",

  //Firefox on Android
  voice => voice.lang == "zh-CN",

  //Chrome on Android
  voice => voice.name == "Chinese China"
);
```

The recommended way to retrieve a voice is the `findVoice()` method, which takes an arbitrary number of `VoicePredicate` arguments, working as follows:

1. It takes the first predicate, trying to apply it to every voice in the TTS system: if the predicate returns `true` for a voice, the entire process ends and such voice is returned.

1. Otherwise, the cycle starts again, applying the subsequent predicate to each voice, and so on.

1. Finally, if no predicate remains, the function returns `null`.

- **Please, note**: for more fine-grained interaction, you can call `getAllVoices()` instead.

- **API safety**: the `findVoice()` and `getAllVoices()` functions are designed to work even if the underlying browser implements no TTS system - by returning, respectively, `null` and an empty array.

### Creating a Speaker

Once you have chosen a voice, you can pass it to the `Speaker` constructor:

```typescript
const mandarinSpeaker = new Speaker(mandarinVoice);
```

You can later reuse the above instance as many times as needed.

### Reading text aloud

Finally, whenever you want to read text aloud, just call the `speak()` method of the `Speaker` instance - passing:

- the _text_ to read

- optional _parameters_

For example:

```typescript
mandarinSpeaker.speak("你好！我喜欢学习汉语！", {
  pitch: 1.7,

  rate: 1.1,

  onEnd() {
    //Called as soon as the reading has finished
  }
});
```

## See also

- [Web Speech API on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)

- [Text-to-speech live demo, by MDN](https://mdn.github.io/dom-examples/web-speech-api/speak-easy-synthesis/)
npm package: @giancosta86/cervantes
Description: Extract and classify Spanish terms from wiki pages, with TypeScript
Author: Gianluca Costa
Latest version: 2.0.0

# CervantesJS

_Extract and classify Spanish terms from wiki pages, with TypeScript_

![GitHub CI](https://github.com/giancosta86/CervantesJS/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fcervantes.svg)](https://badge.fury.io/js/@giancosta86%2Fcervantes)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](./docs/diagrams/overview.png)

**CervantesJS** is a _TypeScript_ library for extracting Spanish terms from wiki pages; even more, it is a plugin for [JardineroJS](https://github.com/giancosta86/JardineroJS), creating a SQLite dictionary of Spanish terms by parsing [Wikcionario](https://es.wiktionary.org/).

## Installation

To install the package as a plugin, please refer to the documentation of [JardineroJS](https://github.com/giancosta86/JardineroJS).

> The current version of the plugin requires Jardinero 2.x

Otherwise, to install it as a library reference within a project:

```bash
npm install @giancosta86/cervantes
```

or

```bash
yarn add @giancosta86/cervantes
```

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

CervantesJS is firstly and foremostly _a plugin_ for [JardineroJS](https://github.com/giancosta86/JardineroJS): please, consult its documentation for details.

However, you can also reference the package as a **standalone library** for _extracting Spanish terms from wiki pages_!

In this case, you can just import names directly from its root:

```typescript
import {...} from "@giancosta86/cervantes"
```

In particular, you may want to consider:

- the `SpanishTerm` union type - and the related types like `Noun`, `Article`, ...

- `extractTerms()` - to _extract Spanish terms_ from a given wiki page

- `SpanishTransform` - a _transform stream_ applying `extractTerms()` to a flow of wiki pages

- `SPANISH_SQLITE_SCHEMA`: a string containing _the DDL code_ for SQLite

- `createSpanishWritableBuilder()` - creating a `WritableBuilder` (from the [sqlite-writable](https://github.com/giancosta86/sqlite-writable) library) with the required _type registrations_ and with a suitable _transaction capacity_

## Further reference

Please, feel free to explore:

- [JardineroJS](https://github.com/giancosta86/JardineroJS) - the web stack itself, designed for _extensible linguistic analysis_

- [JardineroJS - SDK](https://github.com/giancosta86/JardineroJS-sdk) - the development kit for _creating your own plugins_
npm package: @giancosta86/create-marp-slides
Description: Create Marp-based slides from elegant source files
Author: Gianluca Costa
Latest version: 3.1.1

# create-marp-slides

_Create Marp-based slides from elegant source files_

![GitHub CI](https://github.com/giancosta86/create-marp-slides/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fcreate-marp-slides.svg)](https://badge.fury.io/js/@giancosta86%2Fcreate-marp-slides)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](docs/diagrams/overview.png)

**create-marp-slides** is a tool for _generating an entire project structure_ in order to create the slides of a _Marp-based presentation_ - in both **PDF** and **HTML** format.

According to such an _elegant_ project structure, the _Markdown_ source document is decoupled from the custom, _external Sass styling theme_; furthermore, its _package.json_ includes a wide range of **script**'s to handle the different tasks all over its lifecycle.

To create your own project, please run:

> yarn create @giancosta86/marp-slides \[\<directory>]

or

> npm init @giancosta86/marp-slides[@latest] \[\<directory>]

The directory is optional:

- if it does not exist, it will be created

- if omitted, the current working directory will be used, _potentially overwriting but never deleting_ existing files

Please, refer to the generated README file for further details.

## Environment variable

You can set a few environment variables in order to make the app provide default prompt values when creating a new project:

- `CREATE_MARP_SLIDES_AUTHOR_NAME`

- `CREATE_MARP_SLIDES_AUTHOR_EMAIL`

- `CREATE_MARP_SLIDES_AUTHOR_WEBSITE`

- `CREATE_MARP_SLIDES_NODE_VERSION`

## Further references

- [Platonic](https://github.com/giancosta86/platonic) - EJS-based directory reification engine
npm package: @giancosta86/flatten-transform
Description: Modern, configurable flattening stream
Author: Gianluca Costa
Latest version: 1.0.0

# flatten-transform

_Modern, configurable flattening stream_

![GitHub CI](https://github.com/giancosta86/flatten-transform/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fflatten-transform.svg)](https://badge.fury.io/js/@giancosta86%2Fflatten-transform)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](docs/diagrams//overview.png)

**flatten-transform** provides a `FlattenTransform` stream for NodeJS, flattening _arrays_ and _other iterables_ into a _linear sequence_ of items - although the client can optionally set a _maximum nesting level_ so as to constrain the _recursive algorithm_.

Like any other standard `Transform` object, the stream can be plugged into a pipeline, as well as manually controlled.

## Installation

```bash
npm install @giancosta86/flatten-transform
```

or

```bash
yarn add @giancosta86/flatten-transform
```

## Usage

Just create a new instance of `FlattenTransform` and use it in a pipeline, or call its standard methods like `.write()` `.end()`, `.on()`, ...

### Example

This somehow contrived example still shows the simplicity of `FlattenTransform` as well as its support for _pipelines_ and _events_ - among the various stream features.

```typescript
export async function recursiveFlatten(
  source: Iterable<unknown>
): Promise<unknown[]> {
  const linearResult: unknown[] = [];

  const flattenTransform = new FlattenTransform().on("data", item =>
    linearResult.push(item)
  );

  await pipeline(Readable.from(source), flattenTransform);

  return Promise.resolve(linearResult);
}
```

### Constructor parameters

- **maxNestingLevel**: a limit to the recursion performed by the flattening algorithm. The default value is `Infinity` - meaning that _each and every iterable will be recursively flattened_; in contrast, the minimum allowed value - `0` - will actually disable flattening, converting `FlattenTransform` to a pass-through stream

- **highWaterMark**: if present, passed to the base constructor

- **signal**: if present, passed to the base constructor

## Further reference

For additional examples, please consult the unit tests in the source code repository.
npm package: @giancosta86/format-error
Description: Lightweight library for modern Error formatting
Author: Gianluca Costa
Latest version: 2.1.0

# format-error

_Lightweight library for modern Error formatting_

![GitHub CI](https://github.com/giancosta86/format-error/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fformat-error.svg)](https://badge.fury.io/js/@giancosta86%2Fformat-error)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](./docs/diagrams/overview.png)

**format-error** is a _TypeScript_ library designed to easily convert `Error` objects to `string`; in particular, its `formatError()` function provides:

- support for the `cause` property introduced by **ES 2022**

- customizable behaviour via an optional `parts` parameter

- backward compatibility with non-Error objects

## Installation

```bash
npm install @giancosta86/format-error
```

or

```bash
yarn add @giancosta86/format-error
```

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

The library provides the following utility functions:

- `formatError(error[,parts])`: given an error value, returns a string including just the requested error parts (see below). By default, only the **class** and the **message** are included.

  The `error` argument can be anything - although non-`Error` objects will be converted without considering the `parts` argument. More precisely:

  - If the object includes a `message` property, its string conversion will be returned

  - Otherwise, the value itself is converted to string

- `toError(error)`: when receiving an `Error`, the function just returns the argument itself; otherwise, it creates an error whose message is the _stringified_ value

### Error parts

`ErrorParts` is a _flag enum_ - describing the different parts of an `Error` that should appear in the result:

- `Class`: the class

- `Message`: the message

* `CauseChain`: the chain of `cause` errors - if available - displaying the related **class** and **message** parts according to the current format

* `Stack`: the stack trace

You can request multiple error parts by combining the enum values - for example:

```typescript
formatError(
  new URIError("Yogi the Bear"),
  ErrorParts.Class | ErrorParts.CauseChain
);
```

Additionally, the shortcut combination values `Core`, `Main` and `All` are available.

**Please, note**: you must specify **at least one** between `Class` and `Message`; otherwise, the function will throw an error
npm package: @giancosta86/marinero
Description: TypeScript utilities for the browser
Author: Gianluca Costa
Latest version: 1.0.0

# marinero

_TypeScript utilities for the browser_

![GitHub CI](https://github.com/giancosta86/marinero/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fmarinero.svg)](https://badge.fury.io/js/@giancosta86%2Fmarinero)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](./docs/diagrams/overview.png)

**marinero** provides TypeScript utilities for vanilla UI within the browser.

## Installation

The package on NPM is:

> @giancosta86/marinero

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

The `Download` namespace includes:

- `fromDataUrl()` - given a [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs), automatically triggers a download in the browser with the suggested file name

- `objectAsJson()` - given _any object_, converts it to a JSON string downloaded as a text file with the suggested file name
npm package: @giancosta86/more-immutable
Description: Utilities complementing Immutable.js
Author: Gianluca Costa
Latest version: 1.0.0

# more-immutable

_Utilities complementing Immutable.js_

**more-immutable** is a tiny TypeScript library currently containing _sorting_ and _testing_ utilities for [immutable](https://www.npmjs.com/package/immutable).

## Installation

```bash
npm install @giancosta86/more-immutable
```

or

```bash
yarn add @giancosta86/more-immutable
```

The public API entirely resides in the root package index, so one shouldn't reference specific modules.

## Usage

Please, refer to:

- `Comparator` and its `PairSorting` enum

- `expectSorting()` - with a fluent notation that one can use to test sorting algorithms

- `testEqualsAndHashCode()` - to be called within a Jest `describe` block in order to automatically generate tests related to _equality_ and _hash code_ for classes implementing the `ValueObject` interface

## Further references

- [immutable](https://www.npmjs.com/package/immutable)
npm package: @giancosta86/more-jest
Description: TypeScript utilities for Jest
Author: Gianluca Costa
Latest version: 4.1.0

# more-jest

_TypeScript utilities for Jest_

![GitHub CI](https://github.com/giancosta86/more-jest/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fmore-jest.svg)](https://badge.fury.io/js/@giancosta86%2Fmore-jest)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

**more-jest** is a TypeScript library providing enhanced TypeScript support for Jest.

## Installation

The package on NPM is:

> @giancosta86/omnicourse

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

### Matchers

To use the matchers provided by `more-jest` within a project, one needs to:

1. Add the following attribute to the object exported by `jest.config.js`:

   ```typescript
   setupFilesAfterEnv: ["@giancosta86/more-jest/dist/all"],
   ```

1. Add this line to a `global.d.ts` file within the project root directory:

   ```typescript
   import "@giancosta86/more-jest";
   ```

1. Add `"./global.d.ts"` to the `include` array in `tsconfig.json`

## Usage

### Equality.addTesterFor(classType)

Takes a parameter of class `T` containing a method defined as:

```typescript
equals(other: T): boolean {}
```

and registers into Jest an _equality tester_ that:

- returns `undefined` if either equality operand is not an instance of class `T`

- otherwise, returns calls `optionalEquals()` as defined by [@giancosta86/swanlake](https://github.com/giancosta86/swan-lake)

### Equality.test

Runs a suite of equality-related tests, inside a `describe` block having title «equality».

It takes the following parameters:

- a factory used to create a **reference object** and its _equal copies_

- a factory used to create a **different object**, not equal to the reference instance

### Comparison.test

Runs a suite of comparison-related tests based on a `Comp` algorithm, within a «comparison» `describe` block.

It takes an object with the following parameters:

- `comp`: the `Comp` object to be tested

- `scrambledItems`: the items in any chaotic state

- `sortedItems`: the items in the expected order

### Matchers

- `.toBeTrimmed()`: expects that a string be trimmed

- `.toEqualSequence(expected)`: expects that an iterable has the same items, in the same order, as the given iterable. The iterables can be of different types

- `.toHaveSameJson(expected)`: expects that a value be serialized to JSON as the given object

## See also

- [swan-lake](https://github.com/giancosta86/swan-lake)

- [more-jest-io](https://github.com/giancosta86/more-jest-io) - this library's **I/O**-related counterpart

- [jest-extended](https://jest-extended.jestcommunity.dev/) - Additional Jest matchers
npm package: @giancosta86/omnicourse-core
Description: Core model for OmniCourse
Author: Gianluca Costa
Latest version: 2.0.0-alpha.2

# OmniCourse-core

_Core model for OmniCourse_

![GitHub CI](https://github.com/giancosta86/OmniCourse-core/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fomnicourse-core.svg)](https://badge.fury.io/js/@giancosta86%2Fomnicourse-core)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

**OmniCourse-core** is a TypeScript library providing the core model of the [OmniCourse](https://github.com/giancosta86/OmniCourse) project; as a consequence, it is especially useful whenever you need to access its data structures without having to depend on the UI components.

## Installation

First of all, please consider whether you actually need [the full OmniCourse library](https://github.com/giancosta86/OmniCourse): in that case, directly depending on **OmniCourse-core** is not required - as the data structures are exported by **OmniCourse** as well.

The package on NPM is:

> @giancosta86/omnicourse-core

The public API entirely resides in the root package index, so one shouldn't reference specific modules.

For details about installing and using _the whole OmniCourse project_, please refer to the [tutorial wiki page](https://github.com/giancosta86/OmniCourse/wiki/3.-Tutorial).

## Usage

OmniCourse is described in detail in its [wiki](https://github.com/giancosta86/OmniCourse/wiki): for this library, please refer to the [core model](https://github.com/giancosta86/OmniCourse/wiki/2.-Core-model) section.

## See also

- [OmniCourse](https://github.com/giancosta86/OmniCourse)
npm package: @giancosta86/prismatic
Description: TypeScript utilities for NodeJS
Author: Gianluca Costa
Latest version: 1.0.0-alpha.7

# prismatic

_TypeScript utilities for NodeJS_

[![NPM Version](https://img.shields.io/npm/v/%40giancosta86%2Fprismatic?style=for-the-badge&logo=npm&color=forestgreen)](https://www.npmjs.com/package/@giancosta86/prismatic)

**This library is still in alpha version - please, stay tuned!** 🤗🦋
npm package: @giancosta86/rayon
Description: Explore the GLAWI French dictionary, with TypeScript
Author: Gianluca Costa
Latest version: 1.0.0

# RayonJS

_Explore the GLAWI French dictionary, with TypeScript_

![GitHub CI](https://github.com/giancosta86/RayonJS/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Frayon.svg)](https://badge.fury.io/js/@giancosta86%2Frayon)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](./docs/diagrams/overview.png)

**RayonJS** is a _TypeScript_ library dedicated to _extracting_ and _transforming_ a subset of the excellent [GLAWI](http://redac.univ-tlse2.fr/lexiques/glawi.html) French dictionary; even more, it is a plugin for [JardineroJS](https://github.com/giancosta86/JardineroJS), thus creating a SQLite-based dictionary of French terms.

## Installation

To install the package as a plugin, please refer to the documentation of [JardineroJS](https://github.com/giancosta86/JardineroJS).

> The current version of the plugin requires Jardinero 2.x

Otherwise, to install it as a library reference within a project:

```bash
npm install @giancosta86/rayon
```

or

```bash
yarn add @giancosta86/rayon
```

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

RayonJS is designed as _a plugin_ for [JardineroJS](https://github.com/giancosta86/JardineroJS): please, consult its documentation for details.

However, you can also reference the package as a **standalone library** for extracting French terms from GLAWI; in this case, you can just import names directly from its root:

```typescript
import {...} from "@giancosta86/rayon"
```

In particular, you may want to consider:

- `FrenchTransform` - a SAX-based _transform stream_

- the `FrenchTerm` union type - and the related types like `Verb`, `Noun`, `Article`, ...

- `FRENCH_SQLITE_SCHEMA`: a string containing _the DDL code_ for SQLite

- `createFrenchWritableBuilder()` - creating a `WritableBuilder` (from the [sqlite-writable](https://github.com/giancosta86/sqlite-writable) library) with the required _type registrations_ and with a suitable _transaction capacity_

## Special thanks

Special thanks to the magnificent [GLAWI](http://redac.univ-tlse2.fr/lexiques/glawi.html) project.

> Certains droits sont réservés. GLAWI est diffusé sous licence Creative Commons By-SA 3.0.
> Le logo de GLAWI est réalisé par Darwin.

## Further reference

For more details, you are all invited to explore:

- [JardineroJS](https://github.com/giancosta86/JardineroJS) - the web stack itself, designed for _extensible linguistic analysis_

- [JardineroJS - SDK](https://github.com/giancosta86/JardineroJS-sdk) - the development kit for _creating your own plugins_
npm package: @giancosta86/stream-utils
Description: Utilities for streams and iterables
Author: Gianluca Costa
Latest version: 2.2.0

# stream-utils

_Utilities for streams and iterables_

![GitHub CI](https://github.com/giancosta86/stream-utils/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fstream-utils.svg)](https://badge.fury.io/js/@giancosta86%2Fstream-utils)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

**stream-utils** is a minimalist TypeScript library providing utilities for _streams_ and _iterables_.

In particular:

- `AsyncIterable.from()` takes a variable list of arguments of any type, creating an `AsyncIterable` which returns their values. Each argument can be:

  - an `Iterable` or an `AsyncIterable`: in this case, its elements will be yielded, one by one

  - _any other data type_: it will be yielded as it is

- `AsyncIterable.wrapXml()`: takes an `AsyncIterable<string>` of XML chunks and returns another - having a customizable XML opening tag at the beginning and the related closing tag at the end

- `addBatchListener()`: attaches an event listener - to any event of any `Stream` - that gets called only after such event has been notified the number of times

- `Iterable.isEmpty()`: returns if the `Iterable` is empty

- `Iterable.isSupported()`: type guard ensuring that the value is an `Iterable`

- `Iterable.getFirst()`: returns the first item of an `Iterable`; if such `Iterable` is empty, an error is thrown

- `Iterable.equals()`: returns `true` if the two given iterables have the same length - and all the items at the same position are equal according to the given _equality function_ passed as the optional 3rd argument (by default, _strict equality_ via `===`)

- `Iterable.rangeIncluding()`: returns an `Iterable<number>` returning the values from the lower bound L up to the upper bound U - including both. If L > U, an empty `Iterable` is returned instead

## Installation

```bash
npm install @giancosta86/stream-utils
```

or

```bash
yarn add @giancosta86/stream-utils
```

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Further reference

For additional examples, please consult the unit tests in the source code repository.
npm package: @giancosta86/swan-lake
Description: Elegant TypeScript extensions
Author: Gianluca Costa
Latest version: 3.1.0

# swan-lake

_Elegant TypeScript extensions_

![GitHub CI](https://github.com/giancosta86/swan-lake/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fswan-lake.svg)](https://badge.fury.io/js/@giancosta86%2Fswan-lake)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

**swan-lake** is a library providing useful and minimalist extensions for the TypeScript language.

## Installation

The package on NPM is:

> @giancosta86/swan-lake

The public API entirely resides in the root package index, so one shouldn't reference specific modules.

## Usage

- `ImmediateOrPromise<T>` - can be assigned a `T` or a `Promise<T>`

- `AnyClass` is an alias for `Function` - to express a class, even ones having a `private` constructor

- `HasEquals` is an interface having an `equals(other): boolean` method, where `other` belongs to the same type or a structurally compatible one

- `None` is declared as `undefined | null`

- `Optional` is a namespace including:

  - `map` - returns `undefined` if the input value is `null` or `undefined`, but applies the given mapper otherwise

  - `equals` - this function returns `true` if:

    - both `left` and `right` are either `undefined` or `null`

    - `left` and `right` are both defined **and** `left.equals(right)` returns `true`

    **Please, note**: this function does **not** check whether the two operands belong to the same type - according to TypeScript's structural equality; should you have such specific requirement, you'll need to perform a dedicated check.

- `ExpressiveUrl::create` - creates a URL from a string - throwing a descriptive error on failure
npm package: @giancosta86/sync-tools
Description: Synchronization tools for TypeScript
Author: Gianluca Costa
Latest version: 1.0.0

# sync-tools

_Synchronization tools for TypeScript_

![GitHub CI](https://github.com/giancosta86/sync-tools/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Fsync-tools.svg)](https://badge.fury.io/js/@giancosta86%2Fsync-tools)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

## Introduction

**sync-tools** is a TypeScript library providing _functional-style_ synchronization tools.

## Installation

The package on NPM is:

> @giancosta86/sync-tools

The public API entirely resides in the root package index, so one shouldn't reference specific modules.

## Usage

### Barrier

`Barrier` is just an alias for `Promise<void>`; however, it must be created via its `createBarrier()` factory function, which takes the following parameters:

- `requiredTokens`: integer number >= 1; it represents the number of tokens that must be cumulated in order to lift the barrier

- `barrierBody`: a `void`-returning function similar to a `Promise` body, with a fundamental difference:

  - instead of a `(resolve, reject)` pair, it takes an `(addToken, reject)` pair.

    `addToken()` must be called to _add a token to the barrier_, **resolving** the Promise as soon as the required number of tokens has been reached

#### Toy example:

```typescript
//You can also pass (addToken, reject)
await createBarrier(3, addToken => {
  addToken();
  addToken();

  //Just like in any other Promise, you could
  //even throw to cause a reject()

  //This 3rd token lifts the barrier, resolving the Promise
  addToken();
});
```
npm package: @giancosta86/time-utils
Description: Time-related utilities
Author: Gianluca Costa
Latest version: 5.0.0

# time-utils

_Time-related utilities_

![GitHub CI](https://github.com/giancosta86/time-utils/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Ftime-utils.svg)](https://badge.fury.io/js/@giancosta86%2Ftime-utils)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

## Introduction

**time-utils** is a TypeScript library providing time-related types and functions.

## Installation

The package on NPM is:

> @giancosta86/time-utils

The public API entirely resides in the root package index, so one shouldn't reference specific modules.

## Usage

Please, refer to:

- the `IsoDate` class

- the `Milliseconds`, `Seconds` and `Minutes` type aliases

- `delay()`, `epsilonDelay()` and `syncDelay` (especially for tests)

- the `Timestamp` alias - greatly combined with `Date.now()`

- `measureDuration` - to time both sync and async blocks (particularly in tests)
npm package: @giancosta86/unified-logging
Description: Universal, minimalist logging for TypeScript
Author: Gianluca Costa
Latest version: 2.0.0

# unified-logging

_Universal, minimalist logging for TypeScript_

![GitHub CI](https://github.com/giancosta86/unified-logging/actions/workflows/publish-to-npm.yml/badge.svg)
[![npm version](https://badge.fury.io/js/@giancosta86%2Funified-logging.svg)](https://badge.fury.io/js/@giancosta86%2Funified-logging)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](/LICENSE)

![Overview](docs/diagrams/overview.png)

The core of **unified-logging** is the `Logger` interface for **TypeScript**, designed to be used in client code - especially libraries - without depending on a specific logging technology.

Furthermore, this package includes a variety of _utility classes_ that can simplify your logging infrastructure.

## Installation

```bash
npm install @giancosta86/unified-logging
```

or

```bash
yarn add @giancosta86/unified-logging
```

The public API entirely resides in the root package index, so you shouldn't reference specific modules.

## Usage

Just import names from the package index:

```typescript
import {...} from "@giancosta86/unified-logging"
```

### Logger

The `Logger` interface provides just a few core methods:

- `debug(message: string)`

- `info(message: string)`

- `warn(message: string)`

- `error(message: string)`

This is all you need to start working with the library: for example, you might declare a constructor expecting a `Logger` instance among other options - thus letting clients choose the actual implementation.

For example:

```typescript
import { Logger } from "@giancosta86/unified-logging";

function doSomething(logger: Logger): void {
  logger.info("Starting operation...");

  //More code...

  logger.info("Done!");
}

//Console supports the Logger interface!
doSomething(console);
```

### ArrayLogger

Class implementing `Logger` by storing the received messages into `string[]` fields inspectable via read-only properties - for example, `debugMessages`. Especially useful for testing.

### FilterLogger

`Logger` implementation acting as a filter between the client code and another logger; it is based on the `LogLevel` enum, and is especially useful to add filtering to the global `console` object. For example:

```typescript
const filteredConsole = new FilterLogger(console).setLevel(LogLevel.Warn);

//...some code later...

filteredConsole.info("This will not be displayed!");
```

### CompositeLogger

`Logger` implementation that forwards each message to all of its sub-loggers.

## Compatibility

This library is currently tested with:

- the traditional **console** object

- [Pino](https://www.npmjs.com/package/pino)

- [Winston](https://www.npmjs.com/package/winston)

- [Bunyan](https://www.npmjs.com/package/bunyan)

It is because of TypeScript's _structural typing_ that the `Logger` interface actually supports any logger instance providing its methods - with no need for explicit implementation.