All Projects → twfarland → acto

twfarland / acto

Licence: MIT License
A signals library for functional reactive programming

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Labels

Projects that are alternatives of or similar to acto

purescript-wire
Events and Signals for FRP. Monad instances included
Stars: ✭ 13 (-27.78%)
Mutual labels:  signal, frp
sigctx
context with signal in golang
Stars: ✭ 19 (+5.56%)
Mutual labels:  signal
RacJS
implementation of RAC(OC) on JavaScript and replacement of RxJS
Stars: ✭ 13 (-27.78%)
Mutual labels:  signal
frpmgr
Windows 平台的 FRP GUI 客户端
Stars: ✭ 131 (+627.78%)
Mutual labels:  frp
Swift-3-Functional-Programming
Code repository for Swift 3 Functional Programming, published by Packt
Stars: ✭ 78 (+333.33%)
Mutual labels:  frp
frps-nginx-https
nginx反代frps实现https的模板配置文件
Stars: ✭ 44 (+144.44%)
Mutual labels:  frp
EasyBuzzer
The Beep Library For Arduino
Stars: ✭ 63 (+250%)
Mutual labels:  signal
DTMF-Decoder
A Java program to implement a DMTF Decoder.
Stars: ✭ 28 (+55.56%)
Mutual labels:  signal
golib
Open version of common golang libraries useful to many projects.
Stars: ✭ 47 (+161.11%)
Mutual labels:  signal
recurrent
A library for building functional-reactive (FRP) GUIs in Clojurescript
Stars: ✭ 49 (+172.22%)
Mutual labels:  frp
frp-notify
一个专注于消息通知的 frp server manager plugin 实现,让你对进入 frps 的连接了如指掌,不再裸奔。
Stars: ✭ 44 (+144.44%)
Mutual labels:  frp
SciDataTool
SciDataTool is an open-source Python package for scientific data handling. The objective is to provide a user-friendly, unified, flexible module to postprocess any kind of signal. It is meant to be used by researchers, R&D engineers and teachers in any scientific area. This package allows to efficiently store data fields in the time/space or in …
Stars: ✭ 21 (+16.67%)
Mutual labels:  signal
ctxutil
utils for Go context
Stars: ✭ 18 (+0%)
Mutual labels:  signal
reactive-rs
Streams and broadcasts: functional reactive programming in Rust.
Stars: ✭ 28 (+55.56%)
Mutual labels:  frp
signal-cli-rest-api
signal-cli-rest-api is a wrapper around signal-cli and allows you to interact with it through http requests
Stars: ✭ 26 (+44.44%)
Mutual labels:  signal
dtask
DTask is a scheduler for statically dependent tasks.
Stars: ✭ 17 (-5.56%)
Mutual labels:  frp
reflex-dom-ace
Reflex wrapper for the ACE editor
Stars: ✭ 12 (-33.33%)
Mutual labels:  frp
wiki
SakuraFrp Official Document
Stars: ✭ 19 (+5.56%)
Mutual labels:  frp
hassio-addons
Some home assistant addons I manage
Stars: ✭ 16 (-11.11%)
Mutual labels:  signal
binance-pump-alerts
Tracks prices of pairs on binance and notifies when price movements based on pre-defined parameters are met.
Stars: ✭ 65 (+261.11%)
Mutual labels:  signal

acto

A signals library for functional reactive programming. Author: Tim Farland

  • Inspired by Elm and Bacon.js.
  • Written without the use of this, new, or prototype - only simple objects and functions.
  • Miniscule size - ~2kb minified/gzipped.
  • For modular use in node or browsers.
  • Written in Typescript.
  • License: MIT.

Install

	npm install --save acto

Test

	npm test

Importing

	import { create, listen, send /* etc */ } from 'acto'	

Api

Signal interface

Signals are simple objects with the following interface:

interface Signal<T> {
	listeners: Array<(T) => any>
	active:    boolean
	value:     T | null
	stop?:     Function
}

Creating signals

fromDomEvent

Capture events on a dom node.

// fromDomEvent (node: Node, eventName: string): Signal<Event>
const clicks = fromDomEvent(document.body, "click", evt => console.log(evt.target))

fromCallback

A signal that will emit one value, then terminate.

// fromCallback<T> (f: Callback<T>): Signal<T>
const later = fromCallback(callback => setTimeout(() => callback("Finished"), 1000))

fromPromise

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

// fromPromise (promise: Promise<any>): Signal<any>
const wait = fromPromise(new Promise(resolve => setTimeout(() => resolve("Finished"), 1000)))

fromAnimationFrames

// fromAnimationFrames (): Signal<number>
const frames = fromAnimationFrames()

A signal that fires on every window.requestAnimationFrame. Useful in combination with sampleOn.

fromInterval

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

// fromInterval (time: number): Signal<number>
const seconds = fromInterval(1000)

create

Low-level signal creation.

// create<T> (initialValue?: T): Signal<T>
const rawSignal = create()
const rawSignalWithInitialValue = create(123)

Interacting with signals

listen / unlisten

Subscribe / unsubscribe to values emitted by the signal.

// listen<T> (s: Signal<T>, f: Listener<T>): Signal<T>
// unlisten<T> (s: Signal<T>, f: Listener<T>): Signal<T>
function logger (e) { console.log(e) }
listen(clicks, logger)
unlisten(clicks, logger)

send

Send a value to a signal.

// send<T> (s: Signal<T>, v: T): Signal<T>
send(rawSignal, "value")

stop

Stop a signal - no more values will be emitted.

// stop<T> (s: Signal<T>): Signal<T>
stop(rawSignal)

Transforming signals

map

Map values of a signal

// map<T> (f: Mapper<T>, signal: Signal<any>): Signal<T>
const values = map(evt => evt.target.value, fromDomEvent(input, "keydown"))

Map (zip) the latest value of multiple signals

// map<T> (f: Mapper<T>, ...signals: Signal<any>[]): Signal<T>
const areas = map((x, y) => x * y, widthSignal, heightSignal)

filter

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

// filter<T> (f: Filter<T>, s: Signal<T>): Signal<T>
const evens = filter(n => n % 2 === 0, numberSignal)

dropRepeats

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

// dropRepeats<T> (s: Signal<T>): Signal<T>
dropRepeats(numbers)

fold

Fold a signal over an initial seed value.

// fold<T,U> (f: Folder<T,U>, seed: U, s: Signal<T>): Signal<U>
const sum = fold((a, b) => a + b, 0, numbersStream)

merge

Merge many signals into one that emits values from all.

// merge (...signals: Signal<any>[]): Signal<any>
const events = merge(clicks, keypresses)

sampleOn

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

// sampleOn<T,U> (s: Signal<T>, s2: Signal<U>): Signal<T>
const mousePositionsBySeconds = sampleOn(mousePosition, fromInterval(1000))

slidingWindow

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

// slidingWindow<T> (length: number, s: Signal<T>): Signal<T[]>
const trail = slidingWindow(5, mousePosition)

flatMap

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

// flatMap<T,U> (lift: Lifter<T,U>, s: Signal<T>): Signal<U>
const responses = flatMap(evt => fromPromise(ajaxGet("/" + evt.target.value)), keyPresses)

flatMapLatest

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

// flatMap<T,U> (lift: Lifter<T,U>, s: Signal<T>): Signal<U>
flatMapLatest(v => fromPromise(promiseCreator(v)), valueSignal)

debounce

Debounce a signal by a millisecond interval.

// debounce<T> (s: Signal<T>, quiet: number): Signal<T>
const debouncedClicks = debounce(mouseClicks, 1000)

Error handling

To put a signal in an error state, send a native Error object to it, which will set it's value to the error, e.g:

const signal = create()
listen(signal, v => console.log(v))
send(signal, 1) // 1
send(signal, new Error("Disaster has struck")) // [Error: Disaster has struck]

So your listeners need to be handle the case that the the type of any signal value may also be an Error.

As errors are just values, they're propagated downstream by the same mechanism:

const source = create()
const mapped = map(v => v > 1 ? new Error("I can't handle this") : v, source)
listen(mapped, v => console.log(v))
send(source, 1) // 1
send(source, 2) // [Error: I can't handle this]

Errors do not stop signals.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].