Francis is a reactive programming library for TypeScript and JavaScript, inspired by Bacon.js and most, with focus on developer friendly stream semantics, high performance and functional usage.
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),
)
// Hello FRANCIS!!
// Hello FRANCIS!!!
tl;dr I wanted a functional-first, treeshakeable Bacon.js that is 6-10x faster, has lower memory footprint and is written entirely with TypeScript.
npm i --save francis
See API docs (still WIP!) for complete reference of the available functions and their usage.
Because the stream semantics are same (with few differences) in Francis and Bacon, Francis provides a drop-in replacement module for Bacon. The required changes in codebase are:
-import B from "baconjs"
+import B from "francis/bacon"
B.once("Bacon")
.map(x => "Hello " + x + "!")
.map(".toUpperCase")
.onValue(console.log)
You can convert any Francis observable to a "proxied" observable by using F.proxied
utility. Proxied observables are just like their "normal" counterparts, but in
addition they provide a way to traverse the underlying data structure by using
the traditional dot notation. And being typed, of course.
ATTENTION! This feature is experimental and is probably subject to change.
import * as F from "francis"
const state = F.proxied(
F.atom({
msg: "Tsers",
inner: { nums: [1, 2, 4, 5] },
}),
)
// typeof nums === F.Proxied.Atom<num[]>
const { nums } = state.inner
// typeof str === F.Proxied.Property<string>
const str = nums
.map(n => n + 1)
.filter(n => n % 2 === 1)
.join(",")
F.log("str:", str)
F.set(nums, [5, 6])
// logs "3,5" and "7"
MIT