<commit_before># sig
A miniscule signals library by [<NAME>](mailto:<EMAIL>)


Inspired by [Elm](http://elm-lang.org).
Written without the use of `this`, `new`, or `prototype` - only simple objects and functions.
Miniscule size - ~1kb minified/gzipped.
Tests are Todo.


## Signal type

	Signal A :: {
		listeners: [(A -> _)],
		active: boolean,
		value: A || null,
		error: error || null
	}

## Creating signals

Capture events on a dom node.

	// DomNode -> String -> Signal DomEvent
	const clicks = fromDomEvent(document.body, "click", evt => console.log(evt.target))

A signal that will emit one value or an error, then terminate.

	// Promise A -> Signal A
	const wait = fromPromise(new Promise(resolve => setTimeout(() => resolve("Finished"), 1000)))

A signal that emits an integer count of millisecond intervals since it was started.

	// Int -> Signal Int
	const seconds = fromInterval(1000)

Low-level signal creation.

	// Signal A
	const rawSignal = create()

# Interacting with signals

Subscribe to values emitted by the signal.

	// Signal A -> (A -> _) -> Signal A
	listen(clicks, e => console.log(e))

Send a value to a signal.

	// Signal A -> A -> Signal A
	send(rawSignal, "value")

Stop a signal - no more values will be emitted.

	// Signal A -> Signal A
	stop(rawSignal)

# Transforming signals

Map values of a signal

	// (... _ -> B) -> ... Signal _ -> Signal B
	const values = map(evt => evt.target.value, fromDomEvent(input, "keydown"))

Map (zip) the latest value of multiple signals

	// (... _ -> B) -> ... Signal _ -> Signal B
	const areas = map((x, y) => x * y, widthSignal, heightSignal)

Filter a signal, will only emit event that pass the test

	// (A -> Bool) -> Signal A -> Signal A 
	const evens = filter(n => n % 2 === 0, numberSignal)

Only emit if the current value is different to the previous (as compared by `===`). Not a full deduplication.

	// Signal A -> Signal A
	dropRepeats(numbers)

Fold a signal over an initial seed value.

	// (A -> B -> B) -> B -> Signal A -> Signal B
	const sum = fold((a, b) => a + b, 0, numbersStream)

Merge many signals into one that emits values from all.

	// ... Signal _ -> Signal _
	const events = merge(clicks, keypresses)

Take the last value of a stream when another stream emits.

	// Signal A -> Signal B -> Signal A
	const mousePositionsBySeconds = sampleOn(mousePosition, fromInterval(1000))

Emit an array of the last n values of a signal.

	// Int -> Signal A -> Signal [A]
	const trail = slidingWindow(5, mousePosition)

Map values of a signal to a new signal, then flatten the results of all emitted into one signal.

	// (A -> Signal B) -> Signal A -> Signal B
	const responses = flatMap(evt => fromPromise(ajaxGet("/" + evt.target.value)), keyPresses)

The same as above, but only emits values from the latest child signal.

	// (A -> Signal B) -> Signal A -> Signal B
	flatMapLatest(v => fromPromise(promiseCreator(v)), valueSignal)

<commit_msg>readme formatting<commit_after># sig
A miniscule signals library by [<NAME>](mailto:<EMAIL>)


Inspired by [Elm](http://elm-lang.org).
Written without the use of `this`, `new`, or `prototype` - only simple objects and functions.
Miniscule size - ~1kb minified/gzipped.
Tests are Todo.


## Signal type

	Signal A :: {
		listeners: [(A -> _)],
		active: boolean,
		value: A || null,
		error: error || null
	}

## Creating signals

Capture events on a dom node.

```javascript
// DomNode -> String -> Signal DomEvent
const clicks = fromDomEvent(document.body, "click", evt => console.log(evt.target))
```
A signal that will emit one value or an error, then terminate.

```javascript
// Promise A -> Signal A
const wait = fromPromise(new Promise(resolve => setTimeout(() => resolve("Finished"), 1000)))
```
A signal that emits an integer count of millisecond intervals since it was started.

```javascript
// Int -> Signal Int
const seconds = fromInterval(1000)
```
Low-level signal creation.

```javascript
// Signal A
const rawSignal = create()
```
## Interacting with signals

Subscribe to values emitted by the signal.

```javascript
// Signal A -> (A -> _) -> Signal A
listen(clicks, e => console.log(e))
```
Send a value to a signal.

```javascript
// Signal A -> A -> Signal A
send(rawSignal, "value")
```
Stop a signal - no more values will be emitted.

```javascript
// Signal A -> Signal A
stop(rawSignal)
```
## Transforming signals

Map values of a signal

```javascript
// (... _ -> B) -> ... Signal _ -> Signal B
const values = map(evt => evt.target.value, fromDomEvent(input, "keydown"))
```

Map (zip) the latest value of multiple signals

```javascript
// (... _ -> B) -> ... Signal _ -> Signal B
const areas = map((x, y) => x * y, widthSignal, heightSignal)
```
Filter a signal, will only emit event that pass the test

```javascript
// (A -> Bool) -> Signal A -> Signal A 
const evens = filter(n => n % 2 === 0, numberSignal)
```
Only emit if the current value is different to the previous (as compared by `===`). Not a full deduplication.

```javascript
// Signal A -> Signal A
dropRepeats(numbers)
```
Fold a signal over an initial seed value.

```javascript
// (A -> B -> B) -> B -> Signal A -> Signal B
const sum = fold((a, b) => a + b, 0, numbersStream)
```
Merge many signals into one that emits values from all.

```javascript
// ... Signal _ -> Signal _
const events = merge(clicks, keypresses)
```
Take the last value of a stream when another stream emits.

```javascript
// Signal A -> Signal B -> Signal A
const mousePositionsBySeconds = sampleOn(mousePosition, fromInterval(1000))
```
Emit an array of the last n values of a signal.

```javascript
// Int -> Signal A -> Signal [A]
const trail = slidingWindow(5, mousePosition)
```
Map values of a signal to a new signal, then flatten the results of all emitted into one signal.

```javascript
// (A -> Signal B) -> Signal A -> Signal B
const responses = flatMap(evt => fromPromise(ajaxGet("/" + evt.target.value)), keyPresses)
```
The same as above, but only emits values from the latest child signal.

```javascript
// (A -> Signal B) -> Signal A -> Signal B
flatMapLatest(v => fromPromise(promiseCreator(v)), valueSignal)
```

{'fraction_non_alphanumeric': 0.1375609756097561, 'fraction_numerical': 0.0055284552845528455, 'mean_word_length': 3.4507959479015917, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5116948', 'n_tokens_mistral': 2019, 'n_tokens_neox': 1843, 'n_words': 778}