Rx-DataScript
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} = helpersconst {vector, parse, get, hashMap, map, nth, reduce} = moriconst {js: djs} = datascriptconst db = djs.empty_db({name: {[DB_UNIQUE]: DB_UNIQUE_IDENTITY}})const {report$, tx$} = connect(db) // connect is a stream of transactions and stream of reportsconst ivanAdultEntity$ = report$ ::entity$(vector(`name`, `Ivan`)) // make entity stream .skipWhile( Ivan => get(Ivan, `age`) < 18 ) // skip all entity with age < 18const 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// subscribesnames$.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 txnextTx(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.)