npm i --save francis
yarn add francis
<script type="text/javascript" src="https://unpkg.com/francis@2.1.0/dist/francis.min.js"></script>
Francis can be used by using either ES6 module syntax or normal CommonJS module syntax.
Note that francis
package is 100% tree shakeable so if you're using ES6 module syntax,
modern bundlers with UglifyJS (such as Webpack) include only the used functions to your
application!
// ES6 wildcard
import * as F from "francis"
// ES6 named imports
import {map, combineAsArray} from "francis"
// CommonJS
const F = require("francis")
const {map, combineAsArray} = require("francis")
Every operator in Francis is curried. Francis
offers a built-in convenience function called pipe
that allows to "chain"
different operators in a type-safe manner:
import * as F from "francis"
F.pipe(
F.interval(1000, "!"),
F.scan("Francis", (s, x) => s + x),
F.map(s => "Hello " + s.toUpperCase()),
F.skip(2),
F.take(2),
F.onValue(console.log),
)
(observable: Observable<T>) => EventStream<T>
Restores the given observables type information. Fails if the observable's runtime type is not EventSTream.
observable | Observable whose type information will be restored |
EventStream<T>
(observable: Observable<T>) => Property<T>
Restores the given observables type information. Fails if the observable's runtime type is not Property.
observable | Observable whose type information will be restored |
Property<T>
(toWait: Observable<any>, obs: Observable<any>) => Property<boolean>
(toWait: Observable<any>) => (obs: Observable<any>) => Property<boolean>
Creates a Property that indicates whether observable is awaiting the other observable, i.e. has produced a value after the latest value from the other. This is handy for keeping track whether we are currently awaiting an AJAX response
toWait | Observable whose value is waited after each event of |
obs | Observable who is waiting |
Property<boolean>
const searchReq = F.map(toRequest, searchTextChange)
const searchRes = F.flatMapLatest(sendRequest, searchReq)
const isRequestPending = F.awaiting(searchRes, searchReq)
() => Bus<ValueType>
Creates a new Bus
instance.
Bus<ValueType>
(val: ValueType) => Property<ValueType>
Creates a constant Property with the given value.
val | Property's value |
Property<ValueType>
const message = F.constant("Tsers!")
(predicateOrProperty: Predicate<ValueType> | Property<any>, observable: In<ObsType, ValueType>) => Out<ObsType, ValueType>
(predicateOrProperty: Predicate<ValueType> | Property<any>) => (observable: In<ObsType, ValueType>) => Out<ObsType, ValueType>
Filters Observable's values using the given predicate function. Supports
also filtering by Property
- values are passed only when the property has
truthy value.
predicateOrProperty | Predicate function |
observable | Source observable |
Out<ObsType, ValueType>
An Observable
whose values pass the given predicate.
// Filtering by predicate function
F.pipe(F.fromArray([1, 2, 3, 4]),
F.filter(x => x % 2 === 0),
F.log("Result"))
// logs: 2, 4, <end>
// Filtering by Property
const isLoading: Property<boolean> = getLoading(document)
const clicksWhenNotLoading =
F.pipe(F.fromEvents(document.getElementById("myButton"), "click"),
F.filter(F.not(isLoading)))
(observable: In<ObsType, ValueType>) => Out<ObsType, ValueType>
observable |
Out<ObsType, ValueType>
(ctor: PromiseConstructor, obs: Observable<ValueType>) => Promise<ValueType>
(ctor: PromiseConstructor) => (obs: Observable<ValueType>) => Promise<ValueType>
Works same as firstToPromise
but offers way to use custom promise
implementation instead.
ctor | Constructor to the custom promise implementation |
obs | Observable whose first event/error will be resolved to the promise |
Promise<ValueType>
import * as Promise from "bluebird"
const bluebirdPromise = F.firstToCustomPromise(Promise, F.later(100, "tsers!"))
(obs: Observable<ValueType>) => Promise<ValueType>
Returns a Promise which will be resolved with the first event (or error) coming from an Observable. Uses global ES6 promise implementation to construct the promise.
obs | Observable whose first event/error will be resolved to the promise |
Promise<ValueType>
F.firstToPromise(F.sequentially(100, [1, 2, 3])).then(console.log)
// => 1
(events: Array<ValueType | AnyEvent<ValueType>>) => EventStream<ValueType>
Creates an EventStream that produces events from the given array. Once the
stream is activated, all events are emitted at the same tick. You can also send
errors by using F.Error
event in the given array.
events | Events to be emitted to the subscribers |
EventStream<ValueType>
const events = F.fromArray(["foo", new F.Error("fail"), "bar"])
(subscribe: Subscribe<ValueType>) => EventStream<ValueType>
When the last subscriber unsubscribes from this stream, subscriber function gets disposed and the (optional) disposer function gets called.
subscribe | Subscriber function that is called at the stream activation |
EventStream<ValueType>
const events = F.fromBinder(sink => {
sink("Hello")
sink(new F.Error("oops"))
const id = setTimeout(() => sink("world!"), 1000)
return () => {
clearTimeout(id)
}
})
(f: AsyncCallback<ValueType>) => EventStream<ValueType>
Creates an EventStream from a function that accepts a callback. The function is supposed to call its callback just once.
f | Function that gets called at the stream activation |
EventStream<ValueType>
const resultStream = F.fromCallback(cb => {
callSomeLongTask(result => {
cb(processResult(result))
})
})
(target: EventTarget, event: string, args: any[]) => EventStream<ValueType>
(target: EventTarget) => (event: string, args: any[]) => EventStream<ValueType>
Creates an EventStream from events on EventTarget
or EventEmitter
object,
or an object that supports event listeners using on
/off
methods.
target | EventTarget object whose events will be listened |
event | Name of the listened event |
args | Extra args passed to the |
EventStream<ValueType>
const bubbleClicks = F.fromEvent(document.querySelector("#my-button"), "click")
const captureClicks = F.fromEvent(document.querySelector("#my-button"), "click", true)
(f: AsyncNodeCallback<ValueType>) => EventStream<ValueType>
Behaves the same way as fromCallback
, except that it expects the callback
to be called in the Node.js convention: callback(error, data)
, where error is
null
if everything is fine.
f | Function that gets called at the stream activation |
EventStream<ValueType>
const fileContent = F.fromNodeCallback(cb => {
fs.readFile("myFile.txt", cb)
})
(interval: number, f: function) => EventStream<ValueType>
(interval: number) => (f: function) => EventStream<T>
Polls given function with given interval. Function should return plain values
or F.Event
objects. Polling occurs only when there are subscribers to the stream.
Polling ends permanently when f
returns F.End
.
interval | Polling interval in milliseconds |
f | Function that will be called on each tick |
EventStream<ValueType>
const nowEverySec = F.fromPoll(1000, () => Date.now())
(promise: Promise<ValueType>, abort: boolean) => EventStream<ValueType>
Returns a single-value EventStream from the given promise. If promise is rejected, an error event will be emitted instead of value.
promise | Promise to follow |
abort | Optional flag whether or not to call |
EventStream<ValueType>
const response = F.fromPromise(fetch("/my-api.json"))
(period: number, value: ValueType) => EventStream<ValueType>
(period: number) => (value: ValueType) => EventStream<ValueType>
Repeats the single element indefinitely with the given interval
period | Inverval in milliseconds |
value | Repeated value |
EventStream<ValueType>
const messages = F.inverval(1000, "Tsers!")
(x: any) => boolean
Test whether the given value is Francis observable or not
x | Value to be tested |
boolean
(delay: number, value: ValueType) => EventStream<ValueType>
(delay: number) => (value: ValueType) => EventStream<ValueType>
Creates a single-element stream that emits the given value after given delay.
delay | Initial delay in milliseconds |
value | Value to emit |
EventStream<ValueType>
const message = F.later(10000, "Wait for it!")
(project: Projection<InType, OutType>, observable: In<ObsType, InType>) => Out<ObsType, OutType>
(project: Projection<InType, OutType>) => (observable: In<ObsType, InType>) => Out<ObsType, OutType>
Maps the Observable
's values using the given projection function.
project | Projection function |
observable | Source observable |
Out<ObsType, OutType>
An Observable
having project
function applied to its values
F.pipe(F.fromArray([1, 2, 3]),
F.map(x => x + 1),
F.log("Result"))
// logs: 2, 3, 4, <end>
() => EventStream<ValueType>
Creates an EventStream that immediately ends
EventStream<ValueType>
const emptyNum = F.never<number>()
(val: ValueType) => EventStream<ValueType>
Creates a single-event EventStream with the given value. Stream ends immediately after the value has been emitted.
val | Stream's value |
EventStream<ValueType>
const message = F.once("Tsers!")
(generator: Generator<ValueType>) => EventStream<ValueType>
Calls generator function which is expected to return an observable. When the spawned observable ends, the generator is called again to spawn a new observable. If generator returns a falsy value, the stream ends.
generator | Generator function that's supposed to return an observable or |
EventStream<ValueType>
const events = F.repeat(i => i < 10 && F.fromArray([...Array(i).keys()].map(_ => i)))
(interval: number, events: Array<ValueType | AnyEvent<ValueType>>) => EventStream<ValueType>
(interval: number) => (events: Array<ValueType | AnyEvent<ValueType>>) => EventStream<ValueType>
Repeats given elements indefinitely with the given interval.
interval | Interval in milliseconds |
events | Event sequence to repeat indefinitely |
EventStream<ValueType>
const lolbal = F.repeatedly(10, ["lol", "bal"])
(seed: StateType, acc: Accum<StateType, ValueType>, observable: Observable<ValueType>) => Property<StateType>
(seed: StateType, acc: Accum<StateType, ValueType>) => (observable: Observable<ValueType>) => Property<StateType>
(seed: StateType) => (acc: Accum<StateType, ValueType>) => (observable: Observable<ValueType>) => Property<StateType>
(seed: StateType) => (acc: Accum<StateType, ValueType>, observable: Observable<ValueType>) => Property<StateType>
Scans EventStream
or Property
with given seed value and accumulator
function, resulting to a Property
. The seed value is used as an initial
value for the result property.
seed | Seed value to use for the accumulation |
acc | Accumulator function |
observable | Source observable |
Property<StateType>
F.pipe(F.fromArray(["!", "!"]),
F.scan("Hello Francis", (state, value) => state + value),
F.log("Greeting:"))
// logs: "Hello Francis", "Hello Francis!", "Hello Francis!!", <end>
(interval: number, events: Array<ValueType | AnyEvent<ValueType>>) => EventStream<ValueType>
(interval: number) => (events: Array<ValueType | AnyEvent<ValueType>>) => EventStream<ValueType>
Creates an EventStream containing the given values emitted with the given interval.
interval | Interval in milliseconds |
events | Events to emit |
EventStream<ValueType>
Some shit
const numEvery100ms = F.sequentially(100, [1, 2, 3])
(value: ValueType, observable: In<ObsType, ValueType>) => Out<ObsType, ValueType>
(value: ValueType) => (observable: In<ObsType, ValueType>) => Out<ObsType, ValueType>
For EventStream
, this operator adds an extra event with the given value
to the beginning of the stream.
value | Value to be added to the stream / property's initial value |
observable | Source observable |
Out<ObsType, ValueType>
F.pipe(F.once(1),
F.startWith(2),
F.startWith(3),
F.log("EventStream"))
// logs: 3, 2, 1, <end>
F.pipe(F.constant(1),
F.startWith(2),
F.startWith(3),
F.log("Property"))
// logs: 1, <end>
(ctor: PromiseConstructor, obs: Observable<ValueType>) => Promise<ValueType>
(ctor: PromiseConstructor) => (obs: Observable<ValueType>) => Promise<ValueType>
Works same as toPromise
but offers way to use custom promise implementation instead.
ctor | Constructor to the custom promise implementation |
obs | Observable whose last event/error will be resolved to the promise |
Promise<ValueType>
import * as Promise from "bluebird"
const bluebirdPromise = F.toCustomPromise(Promise, F.later(100, "tsers!"))
(obs: Observable<ValueType>) => Promise<ValueType>
Returns a Promise which will be resolved with the last event (or first error) coming from an Observable. Uses global ES6 promise implementation to construct the promise.
obs | Observable whose last event/error will be resolved to the promise |
Promise<ValueType>
F.firstToPromise(F.sequentially(100, [1, 2, 3])).then(console.log)
// => 3