open-index/open-npm huggingface dataset:
npm package: @susiandjames/eslint-plugin-id-denylist-regexp
Description: Drop-in replacement for ESLint's rule id-denylist with support for RegExp
Author: Falco Nogatz
Latest version: 1.0.3

# eslint-plugin-id-denylist-regexp

Drop-in replacement for [ESLint's rule `id-denylist`](https://eslint.org/docs/latest/rules/id-denylist) with support for regular expressions.

## Installation

You'll first need to install [ESLint](https://eslint.org/):

```sh
npm install eslint --save-dev
```

Next, install `eslint-plugin-id-denylist-regexp`:

```sh
npm install @susiandjames/eslint-plugin-id-denylist-regexp --save-dev
```

**Note:** If you installed ESLint globally (using the `-g` flag) then you must also install `eslint-plugin-id-denylist-regexp` globally.

## Usage

Extend your `eslint.config.js` by the rule `susiandjames/id-denylist` as follows:

```js
import susiandjames from "@susiandjames/eslint-plugin-id-denylist-regexp";

export default [
  {
    plugins: {
      susiandjames,
    },
    rules: {
      "susiandjames/id-denylist": [
        "warn",
        "/[0-9]+$/", // Disallow identifiers ending with numbers, e.g., `tmp0`
        "/(black|white)list/i", // Disallow identifiers containing the words "blacklist" and "whitelist" independent of their case sensitivity 
      ],
    },
  },
];
```

**Note:** Since ESLint's options need to be serializable you have to specify regular expressions as strings with a leading slash instead of using JavaScript's `RegExp()` constructor.
npm package: @susicky/design-system-react
Description: Pavel Susicky's personal design system
Author: Pavel Susicky
Latest version: 0.3.1
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# Design System

@susicky/design-system-react is a Design System made by Pavel Susicky. Primary goal was to use it in hobby and side projects to keep same branding across the products. I've opened this repository to public to share it with the community.

## Usage

```bash
yarn add @susicky/design-system-react
```

```typescript
// Import DS stylesheet

import "@susicky/design-system-react/lib/index.css";

// Import components
import { Button } from "@susicky/design-system-react";
```

## Development

### Prerequisites

- `node.js` installed with version specified in `package.json` under engines property.
- `yarn v1` package manager

```bash
# Clone repository
git clone git@github.com:Thesoreon/design-system.git

# Switch current directory to DS
cd design-system

# Install dependencies
yarn install
```
npm package: @susicky/eslint-config-react
Description: Pavel Susicky's personal ESLint configuration for React based projects
Author: Pavel Sušický
Latest version: 1.0.0-alpha.1

# @susicky/eslint-config-react

Disclaimer: This package is not finished 😀

## Installation

```sh
pnpm install -D @susicky/eslint-config-react
```

```json
{
  "extends": "@susicky/eslint-config-react"
}
```
npm package: @susisu/alice
Description: Alice sings
Author: Susisu
Latest version: 0.0.8

# Alice
Alice sings when you mistakenly type `al`.

![screenshot](https://github.com/susisu/alice/wiki/images/al_ja.gif)

## Requirements
* Node.js (>= 4.0)

## Install
``` shell
npm install -g @susisu/alice
```

## Usage
```
al [options]
```

### Options
`-h`, `--help`: output usage information
`-v`, `--version`: output the version number
`-c`, `--colors`: colorize the ASCII arts (white background is recommended)
`-s`, `--speed <value>`: change animation speed (default = 100)
`-S`, `--song <filename>`: load song lyrics from file

### Why don't you sing in English?
``` shell
al -e
```

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/bfjs
Description: Brainf*ck interpreter
Author: Susisu
Latest version: 0.1.2

# BFJS
Brainf*ck interpreter

## Install
``` shell
npm i -g @susisu/bfjs
```

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/catcher
Description: cached fetcher
Author: Susisu
Latest version: 0.7.1

# @susisu/catcher

[![CI](https://github.com/susisu/catcher/workflows/CI/badge.svg)](https://github.com/susisu/catcher/actions?query=workflow%3ACI)

``` shell
# npm
npm i @susisu/catcher
# yarn
yarn add @susisu/catcher
# pnpm
pnpm add @susisu/catcher
```

## Usage

``` typescript
import { Catcher } from "@susisu/catcher";

const catcher = new Catcher({
  fetcher: () => fetchFromSource(params),
});

// data1 = data fetched from the source
const data1 = await catcher.fetch();

// data2 = cached data equal to data1
const data2 = await catcher.fetch();

// expire the cache
catcher.expire();

// data3 = refetched data from the source
const data3 = await catcher.fetch();
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/deform
Description: A form management library for React
Author: Susisu
Latest version: 0.1.0-alpha

# @susisu/deform

[![CI](https://github.com/susisu/deform/workflows/CI/badge.svg)](https://github.com/susisu/deform/actions?query=workflow%3ACI)

A form management library for React (PoC)

``` shell
npm i @susisu/deform
# or
yarn add @susisu/deform
```

## Motivation
TODO

## Usage
TODO

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/est
Description: The easiest way to calculate something.
Author: Susisu
Latest version: 0.0.11

# est
The easiest way to calculate something.

## Installation
Node.js v4.0 or later is required.
``` shell
npm install -g @susisu/est
```

## Usage
### Synopsis
```
est [options] ['prog' | -p progfile] [files ...]
```

### Examples
``` shell
$ cat foo.txt
# comments
1   2   3
4   5   6
7   8   9
$ est '$1' foo.txt
1
4
7
$ est 'sum $1' foo.txt
12
$ est '2 * $1' foo.txt
2
8
14
$ est '[$1, $2, $1 + $2]' foo.txt
1   2   3
4   5   9
7   8   15
$ cat bar.txt
1.0e-1
1.0
1.0e+1
$ est '$$1!2 * $$2!1' foo.txt bar.txt
0.2
5
80
```

### Program syntax
The syntax is very simple:

* Numbers: `123`, `6.02e+23`, ...
* Vectors: `[123, 456]`, ...
* Variables: `x`, `sum`, `PI`, `$1`, `op+` ...
* Functions: `sqrt 3.14`, `log_ 3 9`, `x + y`, ...
* Local bindings: `let x = sum [1, 2, 3] in 2 * x`, ...

NOTE: `f x + y` is recognized as `(f x) + y`, not `f (x + y)`.

### Predefined variables
* Constants: `PI`, `E`, `LN2`, `LN10`, `LOG2E`, `LOG10E`, `SQRT1_2`, `SQRT2`
* Unary functions: `+`, `-`, `abs`, `round`, `floor`, `ceil`, `sqrt`, `exp`, `log`, `log2`, `log10`, `sin`, `cos`, `tan`, `asin`, `acos`, `atan`
* Binary functions: `+`, `-`, `*`, `/`, `%`, `**`, `log_`, `atan_`
* Vector operation functions: index access `!`, `len`, `fst`, `sum`, `prod`, `avg`, `var`, `stddev`, `stderr`

The input data are bound to `$$1`...`$$N` and the columns of the first data are bound to `$1`...`$N`.
The transposed input (the rows are the original columns, and vice versa) are also bound to `$$T1`...`$$TN`.

The unary and binary functions are automatically mapped if applied to vector.

### Options
* `-e`, `--encoding <code>`: set encoding of input files (default = utf8)
* `-f`, `--format <name>`: set fromat type (default = table)
* `-p`, `--program <file>`: read program from `file`
* `-t`, `--transpose`: transpose output
* `-x`, `--exponential`: output numbers in exponential notation
* `-E`, `--extension <file>`: load JavaScript extension; multiple extensions are allowed

## License
[The MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/grass-js
Description: Grass interpreter
Author: Susisu
Latest version: 0.0.6

# Grass-JS
[Grass](http://www.blue.sky.or.jp/grass/) interpreter written in JavaScript

## Usage
``` shell
npm install -g @susisu/grass-js
grass <progfile>
```

For more information, see `grass --help`.

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/grasspiler
Description: Untyped lambda calculus to Grass compiler
Author: Susisu
Latest version: 0.3.2

# Grasspiler
[Untyped lambda calculus](https://en.wikipedia.org/wiki/Lambda_calculus) to [Grass](http://www.blue.sky.or.jp/grass/) compiler.

Grass is an esoteric language based on the untyped lambda calculus, and its program is written by using only three characters: `w`, `W`, and `v`.

## Install
``` shell
npm i -g @susisu/grasspiler
```

## Usage
``` shell
grasspile <srcfile> -o <outfile>
```
For more information about the CLI, see `grasspile -h`.

### Source language spec
The source language is (of course) based on the untyped lambda calculus, and has a simple ML-like syntax.

The syntax is defined as below (though this is very informal and incomplete):

```
<program> ::= <definition>+
<definition> ::= let <ident>+ = <term>
<term> ::= <ident>                            variable
           <term> <term>                      application
           λ<ident>+. <term>                  lambda abstraction
           let <ident>+ = <term> in <term>    local binding
```

A lambda abstraction can be written in several kinds of notation, and also mixture of them.

``` ml
(* lambda calculus-like *)
let S = λx y z. x z (y z)
(* ML-like *)
let S = fun x y z -> x z (y z)
(* Haskell-like *)
let S = \x y z -> x z (y z)
(* mixture of something *)
let S = fun x y z => x z (y z)
(* Of course you can also write it like this *)
let S x y z = x z (y z)
```

The primitives `Out`, `Succ`, `w` and `In` are exposed to the environment,
and the value defined at the end of the source program is called by the Grass VM with itself as an argument.

### Example
Here is a simple program, which takes a character as input, and output it repeatedly.
``` ml
(* fixed-point operator *)
let fix = fun f ->
    (fun x -> f (fun y -> x x y))
    (fun x -> f (fun y -> x x y))

(* infinite loop *)
let loop = fix (fun loop c ->
    let _ = Out c in
    loop c
)

let main _ = loop (In w)
```

Save this source program as `resonance.ml` (it is not an ML program, though) and compile it with `grasspile`.

``` shell
$ grasspile resonance.ml -o resonance.w
$ cat resonance.w
wwWWwwWwwvwwWWWwWWWwvwWWwWWWwwWwwvwwWWWWWWwWWWwwvWWwvwWWWWWWWWWWwwwwwwwwwWWWw
```

Then you can run the compiled program with a Grass compiler/interpreter (for instance, [Grass-JS](https://github.com/susisu/Grass-JS)).

``` shell
$ grass resonance.w
A
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...
```

Stop it if you are satisfied.

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/mte-kernel
Description: The text editor independent part of markdown-table-editor
Author: Susisu
Latest version: 2.1.1

# markdown-table-editor kernel
The text editor independent part of [atom-markdown-table-editor][atom-mte].

![demo](https://github.com/susisu/markdown-table-editor/wiki/images/demo.gif)

[You can try it on your browser!](https://susisu.github.io/mte-demo/)

## Installation
``` shell
npm i -S @susisu/mte-kernel
```

## Usage
Implement an [interface to the text editor][doc-ITextEditor].

``` javascript
interface ITextEditor {
  getCursorPosition(): Point;
  setCursorPosition(pos: Point): void;
  setSelectionRange(range: Range): void;
  getLastRow(): number;
  acceptsTableEdit(row: number): boolean;
  getLine(row: number): string;
  insertLine(row: number, line: string): void;
  deleteLine(row: number): void;
  replaceLines(startRow: number, endRow: number, lines: Array<string>): void;
  transact(func: Function): void;
}
```

And then you can execute [commands][doc-TableEditor] through a `TableEditor` object.

``` javascript
import { TableEditor, options } from "@susisu/mte-kernel";
const textEditor = ...; // interface to the text editor
const tableEditor = new TableEditor(textEditor);
tableEditor.formatAll(options({}));
```

See the [API reference][doc-API] for more information.
It is also good to look into [atom-markdown-table-editor][atom-mte-repo] as a reference implementation.

[doc-API]: https://doc.esdoc.org/github.com/susisu/mte-kernel/identifiers.html
[doc-ITextEditor]:  https://doc.esdoc.org/github.com/susisu/mte-kernel/class/lib/text-editor.js~ITextEditor.html
[doc-TableEditor]:  https://doc.esdoc.org/github.com/susisu/mte-kernel/class/lib/table-editor.js~TableEditor.html
[atom-mte]: https://atom.io/packages/markdown-table-editor
[atom-mte-repo]: https://github.com/susisu/atom-markdown-table-editor

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/ppp
Description: package.json pretty printer
Author: Susisu
Latest version: 0.1.2

# ppp - package.json pretty printer
[![CI](https://github.com/susisu/ppp/workflows/CI/badge.svg)](https://github.com/susisu/ppp/actions?query=workflow%3ACI)

A package information viewer alternative to [`npm-view`](https://docs.npmjs.com/cli/view.html).

``` shell
npm i -g @susisu/ppp
```

## Usage
``` shell
# show package information on npm
ppp <pkg>
# or of a local one
ppp < package.json
```

### Options
- `-f, --include-field <name>`: Include an additional field. This option is repeatable. See [Configurations](#configurations) or `-h, --help` for the list of available field names.
- `-x, --exclude-field <name>`: Exclude a field. This option is repeatable.
- `-w, --wrap <int>`: Wrap output to the specified size. This overrides the setting of the [configurations file](#configurations).

### Configurations
You can place `~/.config/ppp/config.yaml` to customize output fields and text wrapping size. The default configurations are as follows:

``` yaml
fields:
  - name
  - version
  # - installed
  - description
  # - keywords
  - license
  - author
  # - maintainers
  - homepage
  # - npm
  # - repository
  # - tarball
  # - shasum
  # - module
  # - types
  - binaries
  - engines
  - os
  - cpu
  # - dependencies
  - peerDependencies
  # - optionalDependencies
  # - devDependencies
  - tags
wrap: 80
```

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/primitive-debounce
Description: Provides primitive functionality to implement debounce functions
Author: Susisu
Latest version: 0.4.0

# primitive-debounce

[![CI](https://github.com/susisu/primitive-debounce/workflows/CI/badge.svg)](https://github.com/susisu/primitive-debounce/actions?query=workflow%3ACI)

Provides primitive functionality to implement debounce functions.

``` shell
# npm
npm i @susisu/primitive-debounce
# yarn
yarn add @susisu/primitive-debounce
# pnpm
pnpm add @susisu/primitive-debounce
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/promise-utils
Description: Promise utilities
Author: Susisu
Latest version: 0.2.0

# @susisu/promise-utils

[![CI](https://github.com/susisu/promise-utils/workflows/CI/badge.svg)](https://github.com/susisu/promise-utils/actions?query=workflow%3ACI)

Promise utilities

``` shell
# npm
npm i @susisu/promise-utils
# yarn
yarn add @susisu/promise-utils
# pnpm
pnpm add @susisu/promise-utils
```

## Usage

### `triplet`

Creates a triplet of a promise and its resolve and reject functions.

``` typescript
import { triplet } from "@susisu/promise-utils";

const [promise, resolve, reject] = triplet<number>();

resolve(42);

promise.then(res => {
  console.log(res); // -> 42
});
```

### `attachActions`

Attaches cancellable actions to a promise.

``` typescript
import { triplet, attachActions } from "@susisu/promise-utils";

const [promise, resolve, reject] = triplet<number>();

const [cancel] = attachActions(
  promise,
  res => { console.log(res); },
  err => { console.log(err); }
);

cancel();

resolve(42); // no output
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/react-use-source-sink
Description: Creates a pair of source and sink
Author: Susisu
Latest version: 0.2.0

# @susisu/react-use-source-sink

[![CI](https://github.com/susisu/react-use-source-sink/workflows/CI/badge.svg)](https://github.com/susisu/react-use-source-sink/actions?query=workflow%3ACI)

``` shell
# npm
npm i @susisu/react-use-source-sink
# yarn
yarn add @susisu/react-use-source-sink
# pnpm
pnpm add @susisu/react-use-source-sink
```

## Usage

``` tsx
import React, { useEffect } from "react";
import { useSourceSink } from "@susisu/react-use-source-sink";

const Hello: React.FC = () => {
  const [source, sink] = useSourceSink<HTMLElement | null>(null);
  useEffect(() => {
    const elem = source();
    // ...
  });
  return (
    <p ref={sink}>Hello!</p>
  );
};
```

### Why?

The following code does not pass the type check.

``` tsx
import React, { useRef } from "react";

const Hello: React.FC = () => {
  const ref = useRef<HTMLElement | null>(null);
  return (
    <p ref={ref}>Hello!</p>
  );
};
```

This is because a reference created by `useRef` is both readable and writable, and basically *invariant* in terms of types, which means it cannot be up- nor down-casted. A reference to `HTMLElement` cannot be passed to the `ref` prop of a `p` element, which requires a reference to `HTMLParagraphElement`.

To pass the type check, we can use a *callback ref*, which is basically *contravariant* and can be safely passed to a concrete element.

``` tsx
import React, { useRef, useCallback } from "react";

const Hello: React.FC = () => {
  const ref = useRef<HTMLElement | null>(null);
  const callbackRef = useCallback((elem: HTMLElement | null): void => {
    ref.current = elem;
  }, []);
  return (
    <p ref={callbackRef}>Hello!</p>
  );
};
```

`useSourceSink` simplifies this boilerplate.

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/tesseract
Description: session and transaction
Author: Susisu
Latest version: 0.1.0

# @susisu/tesseract

[![Build Status](https://travis-ci.com/susisu/tesseract.svg?branch=master)](https://travis-ci.com/susisu/tesseract)

``` shell
npm i @susisu/tesseract
# or
yarn add @susisu/tesseract
```

## Usage
### Database
Manipulating database with transaction.

``` typescript
import { AsyncSession } from "@susisu/tesseract";

const session = new AsyncSession({
  async initialize() {
    await begin();
  },
  async finalize() {
    await commit();
  },
  async handleError() {
    await rollback();
  },
});

await session.transact(async () => {
  await updateA(session);
  await updateB(session);
});

async function updateA(session: AsyncSession): Promise<void> {
  await session.transact(async () => {
    await updateA0(session);
    await updateA1(session);
  });
}
```

### Editor
Executing multiple edit operations while pushing at most one history to the undo buffer.

``` typescript
import { Session } from "@susisu/tesseract";

const session = new Session<State>({
  initialize() {
    return dumpState();
  },
  finalize(oldState: State) {
    const newState = dumpState();
    if (!newState.equals(oldState)) {
      pushHistory(oldState);
    }
  },
});

session.transact(() => {
  editA(session);
  editB(session);
});
```

### Emitter
Updating a state multiple times while emitting at most one update event.

``` typescript
import { Session } from "@susisu/tesseract";

const session = new Session<State>({
  initialize() {
    return dumpState();
  },
  finalize(oldState: State) {
    const newState = dumpState();
    if (!newState.equals(oldState)) {
      emitUpdate();
    }
  },
});

session.transact(() => {
  updateA(session);
  updateB(session);
});
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/tf-random
Description: Splittable pseudorandom number generator
Author: Susisu
Latest version: 0.2.0

# tf-random.js
[![Build Status](https://travis-ci.com/susisu/tf-random.js.svg?branch=master)](https://travis-ci.com/susisu/tf-random.js)

Pure JavaScript port of [tf-random](http://hackage.haskell.org/package/tf-random-0.5), splittable pseudorandom number generator.

## Installation
``` shell
# npm
npm i @susisu/tf-random
# yarn
yarn add @susisu/tf-random
```

## Usage
``` javascript
import { TFGen } from "@susisu/tf-random";

// Initialize a generator.
const gen = TFGen.init();

// Call `next` to generate a random number (32-bit signed integer) and a new generator.
const [x, nextGen] = gen.next();

// Call `split` to derive two effectively independent generators.
const [gen1, gen2] = nextGen.split();
```

You can also call `gen.splitn(n, i)` to derive `2 ** n` independent generators and obtain `i`th of them.

The package also provides some utility functions `random`, `randomInt32`, `randomInt32R`, etc. for generating random numbers.

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/ts-dimensional
Description: Dimensional Quantities in TypeScript
Author: Susisu
Latest version: 0.1.0

# @susisu/ts-dimensional
[![Build Status](https://travis-ci.com/susisu/ts-dimensional.svg?branch=master)](https://travis-ci.com/susisu/ts-dimensional)

PoC: Dimensional Quantities in TypeScript

**NOTE: This is an experimental package and not suitable for production use.**

``` shell
npm i @susisu/ts-dimensional
# or
yarn add @susisu/ts-dimensional
```

TypeScript 4.0+ is required.

## Example

``` typescript
import { mass, length, mks, cgs, add, mul, conv } from "@susisu/ts-dimensional";

const m1 = mass(1, mks);
const m2 = mass(2, mks);
const m3 = mass(3, cgs);

const l1 = length(1, mks);
const l2 = length(2, mks);
const l3 = length(3, cgs);

add(m1, m2); // ok
add(m1, l1); // error: dimensions mismatch
add(m1, m3); // error: unit systems mismatch

mul(m1, l1); // ok
add(mul(m1, l1), mul(m2, l2)); // ok
mul(m1, l3); // error: unit systems mismatch

const m4 = conv(m1, cgs);
add(m3, m4); // ok
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/tyde
Description: Typed event emitter
Author: Susisu
Latest version: 0.4.0

# @susisu/tyde

[![CI](https://github.com/susisu/tyde/workflows/CI/badge.svg)](https://github.com/susisu/tyde/actions?query=workflow%3ACI)

Typed event emitter

## Installation

``` shell
# npm
npm i @susisu/tyde
# yarn
yarn add @susisu/tyde
# pnpm
pnpm add @susisu/tyde
```

## Usage

tyde provides API that is similar to [EventEmitter](https://nodejs.org/api/events.html) and [event-kit](https://github.com/atom/event-kit).

The simplest usage is subscribing events with `.on()` and emitting events with `.emit()`.

``` typescript
import { Emitter } from "@susisu/tyde";

const emitter = new Emitter();

const subscription = emitter.on("change", value => {
  console.log(value);
});

emitter.emit("change", 42); // -> 42
```

Subscriptions can be unsubscribed by calling `.unsubscribe()`.

``` typescript
subscription.unsubscribe();
emitter.emit("change", 0); // no output
```

The curried version of `.on()` is also available.

``` typescript
const onChange = emitter.on("change");
const subscription = onChange(value => { /* ... */ });
```

You can optionally restrict types of emitted values by giving a dictionary to `Emitter`'s type parameter.

``` typescript
const emitter = new Emitter<{
  "change": number,
  "destroy": void,
}>();

emitter.emit("change", 42);     // ok
emitter.emit("destroy");        // ok
emitter.emit("foo", 42);        // type error: unknown event
emitter.emit("change", "test"); // type error: mismatched type
```

## Difference from other event emitters

By design, tyde has some difference from other event emitter libraries:

- No wildcards, because of the strongly typed interface.
- Events are emitted asynchronously by default.
  - Usually event handlers should not care whether it is called synchronously or asynchronously.
  - There is also a synchronous version `.emitSync()`, but it is not generally recommended.
- Invocation order of event handlers is not guaranteed in any way.
  - Specifying execution order in a less explicit way will lower the readability of code.
  - If you still want one, invoke functions sequentially in one event handler, or separate the event into multiple stages.

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/type-of-schema
Description: Derives TypeScript type from JSON Schema
Author: Susisu
Latest version: 0.4.0

# @susisu/type-of-schema

[![CI](https://github.com/susisu/type-of-schema/workflows/CI/badge.svg)](https://github.com/susisu/type-of-schema/actions?query=workflow%3ACI)

Derives TypeScript type from [JSON Schema](https://json-schema.org/)

## Installation

``` shell
# npm
npm i @susisu/type-of-schema
# yarn
yarn add @susisu/type-of-schema
# pnpm
pnpm add @susisu/type-of-schema
```

## Usage

``` typescript
import type { TypeOfSchema } from "@susisu/type-of-schema";

const schema = {
  type: "object",
  properties: {
    "a": { type: "number" },
    "b": { type: "string" },
  },
  required: ["b"],
} as const;

// T = { a?: number; b: string }
type T = TypeOfSchema<typeof schema>;
```

Do not forget `as const` in the schema declaration. Without it, you will not get the full information of the schema.

## Supported Schemas

- `const`
- `enum`
- `null`
- `number` / `integer`
- `string`
- `boolean`
- `array` (`items` and `additionalItems`) 
- `object` (`properties`, `required`, and `additionalProperties`)
- `oneOf`
- `allOf`

## Limitations

For JSON Schema object types `S` and `T`, `S extends T` does not imply `TypeOfSchema<S> extends TypeOfSchema<T>`. In other words, a type derived from a schema can be inconsistent with what the schema actually describes. This can be observed, for example, when upcasting a schema containing `required`:

``` typescript
const schema1 = {
  type: "object",
  required: ["a"],
} as const;

// T1 = { a: Value }
type T1 = TypeOfSchema<typeof schema1>;

const schema2: {
  type: "object";
  required: ("a" | "b")[];
} = schema1;

// T2 = { a: Value; b: Value }
// but b is actually not required
type T2 = TypeOfSchema<typeof schema2>;
```

To avoid this, do always pass the original schema to `TypeOfSchema`.

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/typefuck
Description: A type-level Brainfuck interpreter in TypeScript
Author: Susisu
Latest version: 0.6.0

# @susisu/typefuck

[![CI](https://github.com/susisu/typefuck/workflows/CI/badge.svg)](https://github.com/susisu/typefuck/actions?query=workflow%3ACI)

A type-level [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) interpreter in TypeScript

``` shell
# npm
npm i --save @susisu/typefuck
# yarn
yarn add @susisu/typefuck
# pnpm
pnpm add @susisu/typefuck
```

## Example

[Playground](https://www.typescriptlang.org/play#code/JYWwDg9gTgLgBDAnmApnA3nAQlAhsAOwDMBXAYwGs4BfOIqCEOAIgAEBnE94TgeiVSlKzANwAoMQLQAFBgHM8TALwsAfABoA2hoC6AHk0A6PTtGTkaAJIEwJeCuYAJFABsXEdXADu0FwBMAQjMpOAB5O1t7bDxCIQo9WQgFXBBPa0jVcV5eOFyAPQB+MSA)

``` typescript
import type { Brainfuck } from "@susisu/typefuck";

type Program = ">,[>,]<[.<]";
type Input = "Hello, world!";
type Output = Brainfuck<Program, Input>; // = "!dlrow ,olleH"
```

## License

[MIT License](http://opensource.org/licenses/mit-license.php)

## Author

Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))
npm package: @susisu/whitespace-js
Description: Whitespace interpreter
Author: Susisu
Latest version: 0.0.8

# Whitespace-JS
[Whitespace](https://esolangs.org/wiki/Whitespace) interpreter written in JavaScript

## Usage
```
npm install -g @susisu/whitespace-js
wspace <progfile>
```
It also contains `ws2unws` and `unws2ws` which convert a Whitespace program into a human readable format (named *UnWhitespace*) and vice versa.

For more information, see `wspace -h`.

## Notes
* Numbers and arithmetic have only 32bit precision (not arbitrary precision as the original implementation).
* Programs not terminated by `[LF][LF][LF]` will produce warnings (use `-w, --no-warnings` to suppress them).

## License
[MIT License](http://opensource.org/licenses/mit-license.php)

## Author
Susisu ([GitHub](https://github.com/susisu), [Twitter](https://twitter.com/susisu2413))