Rx-DataScript [](https://travis-ci.org/typeetfunc/rx-datascript)
April 23, 2016 ยท View on GitHub
RxJS wrapper for DataScript. DataScript connection represented as reports stream and transactions stream. Reports stream is formed from transactions stream with using scan function.
Example
import {datascript, mori, helpers} from 'datascript-mori'
import {connect, nextTx, q$, entity$} from '../src/index'
import 'rxjs/add/operator/skipWhile'
import 'rxjs/add/operator/filter'
const {DB_ID, DB_ADD, TX_DATA, TX_META, DB_AFTER, DB_BEFORE, DB_UNIQUE, DB_UNIQUE_IDENTITY} = helpers
const {vector, parse, get, hashMap, map, nth, reduce} = mori
const {js: djs} = datascript
const db = djs.empty_db({name: {[DB_UNIQUE]: DB_UNIQUE_IDENTITY}})
const {report$, tx$} = connect(db) // connect is a stream of transactions and stream of reports
const ivanAdultEntity$ = report$
::entity$(vector(`name`, `Ivan`)) // make entity stream
.skipWhile(
Ivan => get(Ivan, `age`) < 18
) // skip all entity with age < 18
const names$ = report$
.filter(
report => find(
map(report, tx => nth(tx, 2)),
`name`
)
) // filter all tx which dont affect names of entities
::q$(parse(`[:find [?n ...] :where [?e "name" ?n]]`)) // make results of the query stream
// subscribes
names$.subscribe(
names => console.log(
`Names of users: ${reduce(names, (acc, name) => acc + ', ' + name)}`
)
)
ivanAdultEntity$.subscribe(Ivan => console.log(`Ivan age ${get(Ivan, 'age')} years`))
// Add some tx
nextTx(tx$, vector(
vector(DB_ADD, 1, `name`, `Ivan`),
vector(DB_ADD, 1, `age`, 17)
))
nextTx(tx$, vector(
vector(DB_ADD, 1, `age`, 18)
))
nextTx(tx$, vector(
vector(DB_ADD, 1, `age`, 19)
))
nextTx(tx$, vector(
hashMap(
DB_ID, 2,
"name", "Igor",
"age", 35
)
));
/* Output entity subscriber
Ivan age 18 years
Ivan age 19 years
*/
/* Output names subscriber
Names of users: Ivan
Names of users: Ivan, Igor
*/
API
createAnyQueryStream(queryFunc: Function, distinctUntilChangedFunc: Function): Function: Basic high order function for wrapping any query function in stream. Second optional argument is function that compare results of query.connect(db: DataScript DB): {report$: Observable<Report>, tx$: Observable<tx>}: Function for creating observable of report and tx from DataScript DB.nextTx(tx$: Observable<tx>, ...tx: Array<tx>):Void: Function for applying array of transactions to stream of tx.
Reactive analogues DataScript API
q$entity$filter$pull$pullMany$datoms$seekDatoms$indexRange$
All functions takes the first argument observable of reports. Also you can pass observable of reports in this with using bind operator - report$::q$(...). Rest arguments is equals list of arguments in original function(see DataScript Docs)
Why?
DataScript transaction API based on callbacks. Callbacks is a bad, because using callbacks, you can not work with events as first-class citizen value. Reactive streams allow the manipulate events as first-class citizen values and provide many operators for proccessing event streams.
Roadmap
- Interoperability with other streaming libs(Most, Kefir, etc.)