reactivedb
Advanced tools
Comparing version 0.9.11-alpha.0 to 0.9.11
{ | ||
"name": "reactivedb", | ||
"version": "0.9.11-alpha.0", | ||
"version": "0.9.11", | ||
"description": "Reactive ORM for Lovefield", | ||
"main": "index.js", | ||
"main": "dist/cjs/index.js", | ||
"module": "dist/es/index.js", | ||
"scripts": { | ||
@@ -19,3 +20,3 @@ "build_all": "npm-run-all build_cjs build_module_es build_test", | ||
"cover": "rm -rf ./.nyc_output ./coverage && NODE_ENV=test nyc --reporter=html --reporter=lcov --exclude=node_modules --exclude=spec-js/test --exclude=spec-js/src/storage/lovefield.js --exclude=spec-js/src/shared/Logger.js --exclude=spec-js/src/utils/option.js --exclude=spec-js/src/utils/valid.js tman --mocha spec-js/test/run.js", | ||
"lint": "tslint -c tslint.json src/*.ts --project ./tsconfig.json --type-check src/**/*.ts src/**/**/*.ts ./test/*.ts ./test/**/*.ts ./test/**/**/*.ts -e ./test/e2e/*.ts", | ||
"lint": "tslint -c tslint.json src/*.ts --project ./tsconfig.json --type-check src/**/*.ts ./test/**/*.ts -e ./test/e2e/*.ts", | ||
"start": "webpack-dev-server --inline --colors --progress --port 3000", | ||
@@ -45,3 +46,4 @@ "start-demo": "webpack-dev-server --config ./example/webpack.config.js --inline --colors --progress --port 3001 --open", | ||
{ | ||
"name": "Saviio" | ||
"name": "Saviio", | ||
"email": "sirius0x9@gmail.com" | ||
}, | ||
@@ -48,0 +50,0 @@ { |
@@ -7,2 +7,4 @@ [](https://circleci.com/gh/ReactiveDB/core) | ||
[](https://greenkeeper.io/) | ||
一个 Reactive 风格的前端 ORM。基于 [Lovefield](https://github.com/google/lovefield) 与 [RxJS](https://github.com/ReactiveX/rxjs)。 | ||
@@ -9,0 +11,0 @@ |
@@ -80,4 +80,40 @@ import { Observer } from 'rxjs/Observer' | ||
private change$: Observable<T[]> | ||
private _change$: Observable<T[]> | null = null | ||
private get change$ (): Observable<T[]> { | ||
if (this._change$) { | ||
return this._change$ | ||
} | ||
const { db, limit } = this | ||
let { skip } = this | ||
skip = limit && !skip ? 0 : skip | ||
const observeOn = (query: lf.query.Select) => | ||
Observable.create((observer: Observer<T[]>) => { | ||
const listener = () => { | ||
this.getValue(query) | ||
.then(r => observer.next(r as T[])) | ||
.catch(e => observer.error(e)) | ||
} | ||
db.observe(query, listener) | ||
listener() | ||
return () => this.db.unobserve(query, listener) | ||
}) as Observable<T[]> | ||
const changesOnQuery = limit || skip | ||
? this.buildPrefetchingObserve() | ||
.switchMap((pks) => | ||
observeOn(this.getQuery(this.inPKs(pks))) | ||
) | ||
: observeOn(this.getQuery()) | ||
return lfIssueFix(changesOnQuery) | ||
.publishReplay(1) | ||
.refCount() | ||
} | ||
private set change$ (dist$: Observable<T[]>) { | ||
this._change$ = dist$ | ||
} | ||
private consumed = false | ||
@@ -145,38 +181,2 @@ private predicateBuildErr = false | ||
this.predicateProvider = this.normPredicateProvider(predicateProvider) | ||
skip = limit && !skip ? 0 : skip | ||
if (limit || skip) { | ||
this.change$ = this.buildPrefetchingObserve() | ||
.switchMap(pks => { | ||
return Observable.create((observer: Observer<T[]>) => { | ||
const query = this.getQuery(this.inPKs(pks)) | ||
const listener = () => { | ||
this.getValue(query) | ||
.then(r => observer.next(r as T[])) | ||
.catch(e => observer.error(e)) | ||
} | ||
listener() | ||
db.observe(query, listener) | ||
return () => this.db.unobserve(query, listener) | ||
}) as Observable<T[]> | ||
}) | ||
.publishReplay(1) | ||
.refCount() | ||
} else { | ||
this.change$ = Observable.create((observer: Observer<T[]>) => { | ||
const query = this.getQuery() | ||
const listener = () => { | ||
this.getValue(query) | ||
.then(r => observer.next(r as T[])) | ||
.catch(e => observer.error(e)) | ||
} | ||
db.observe(query, listener) | ||
listener() // 把 listener 放到 observe 后边执行,是 lovefield issue#209 | ||
// https://github.com/google/lovefield/issues/209 | ||
// 的一个 workaround。issue 修复后,listener 也可以放在 observe | ||
// 前面执行。 | ||
return () => this.db.unobserve(query, listener) | ||
}) | ||
.publishReplay(1) | ||
.refCount() | ||
} | ||
this.select = lselect.toSql() | ||
@@ -279,3 +279,3 @@ } | ||
const listener = () => { | ||
rangeQuery.exec() | ||
return rangeQuery.exec() | ||
.then((r) => { | ||
@@ -286,12 +286,36 @@ observer.next(r.map(v => v[this.shape.pk.name])) | ||
} | ||
listener() | ||
this.db.observe(rangeQuery, listener) | ||
listener().then(() => { | ||
this.db.observe(rangeQuery, listener) | ||
}) | ||
return () => this.db.unobserve(rangeQuery, listener) | ||
}) | ||
/** | ||
* TODO 这里返回的 observable 第一个值和第二个值在它们的值不为空 | ||
* 的时候是重复的,也许有必要省去做优化;但不能简单 skip(1),因为 | ||
* 那样会导致不能推出空结果集。 | ||
*/ | ||
} | ||
} | ||
interface LfIssueAcc<T> { | ||
calledCount: number | ||
shouldSkip: boolean | ||
result: T[] | ||
} | ||
/** | ||
* Lovefield observe 出来的推送,第一次和第二次在它们的值不为空 | ||
* 的时候是重复的,这里做优化,省去重复;但不是简单的 skip(1),因为 | ||
* 那样会导致不能推出空结果集。详见:Lovefield issue#215 | ||
*/ | ||
const lfIssueFix = <T>(changes: Observable<T[]>) => | ||
(changes as any) | ||
.scan((ret: LfIssueAcc<T>, x: T[]) => { | ||
ret.calledCount = ret.calledCount + 1 | ||
const { calledCount } = ret | ||
ret.shouldSkip = !!(x && x.length) && calledCount === 2 | ||
ret.result = x | ||
return ret | ||
}, { | ||
shouldSkip: false, | ||
calledCount: 0 | ||
}) | ||
.filter((x: LfIssueAcc<T>) => !x.shouldSkip) | ||
.map((x: LfIssueAcc<T>) => x.result) |
@@ -1,1 +0,1 @@ | ||
export default '0.9.10' | ||
export default '0.9.11' |
@@ -19,2 +19,3 @@ /// <reference types="lovefield" /> | ||
select: string; | ||
private _change$; | ||
private change$; | ||
@@ -21,0 +22,0 @@ private consumed; |
@@ -13,3 +13,2 @@ "use strict"; | ||
function Selector(db, lselect, shape, predicateProvider, limit, skip, orderDescriptions) { | ||
var _this = this; | ||
this.db = db; | ||
@@ -23,42 +22,6 @@ this.lselect = lselect; | ||
this.mapFn = mapFn_1.mapFn; | ||
this._change$ = null; | ||
this.consumed = false; | ||
this.predicateBuildErr = false; | ||
this.predicateProvider = this.normPredicateProvider(predicateProvider); | ||
skip = limit && !skip ? 0 : skip; | ||
if (limit || skip) { | ||
this.change$ = this.buildPrefetchingObserve() | ||
.switchMap(function (pks) { | ||
return Observable_1.Observable.create(function (observer) { | ||
var query = _this.getQuery(_this.inPKs(pks)); | ||
var listener = function () { | ||
_this.getValue(query) | ||
.then(function (r) { return observer.next(r); }) | ||
.catch(function (e) { return observer.error(e); }); | ||
}; | ||
listener(); | ||
db.observe(query, listener); | ||
return function () { return _this.db.unobserve(query, listener); }; | ||
}); | ||
}) | ||
.publishReplay(1) | ||
.refCount(); | ||
} | ||
else { | ||
this.change$ = Observable_1.Observable.create(function (observer) { | ||
var query = _this.getQuery(); | ||
var listener = function () { | ||
_this.getValue(query) | ||
.then(function (r) { return observer.next(r); }) | ||
.catch(function (e) { return observer.error(e); }); | ||
}; | ||
db.observe(query, listener); | ||
listener(); // 把 listener 放到 observe 后边执行,是 lovefield issue#209 | ||
// https://github.com/google/lovefield/issues/209 | ||
// 的一个 workaround。issue 修复后,listener 也可以放在 observe | ||
// 前面执行。 | ||
return function () { return _this.db.unobserve(query, listener); }; | ||
}) | ||
.publishReplay(1) | ||
.refCount(); | ||
} | ||
this.select = lselect.toSql(); | ||
@@ -127,2 +90,39 @@ } | ||
}; | ||
Object.defineProperty(Selector.prototype, "change$", { | ||
get: function () { | ||
var _this = this; | ||
if (this._change$) { | ||
return this._change$; | ||
} | ||
var _a = this, db = _a.db, limit = _a.limit; | ||
var skip = this.skip; | ||
skip = limit && !skip ? 0 : skip; | ||
var observeOn = function (query) { | ||
return Observable_1.Observable.create(function (observer) { | ||
var listener = function () { | ||
_this.getValue(query) | ||
.then(function (r) { return observer.next(r); }) | ||
.catch(function (e) { return observer.error(e); }); | ||
}; | ||
db.observe(query, listener); | ||
listener(); | ||
return function () { return _this.db.unobserve(query, listener); }; | ||
}); | ||
}; | ||
var changesOnQuery = limit || skip | ||
? this.buildPrefetchingObserve() | ||
.switchMap(function (pks) { | ||
return observeOn(_this.getQuery(_this.inPKs(pks))); | ||
}) | ||
: observeOn(this.getQuery()); | ||
return lfIssueFix(changesOnQuery) | ||
.publishReplay(1) | ||
.refCount(); | ||
}, | ||
set: function (dist$) { | ||
this._change$ = dist$; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Selector.prototype, "rangeQuery", { | ||
@@ -266,3 +266,3 @@ get: function () { | ||
var listener = function () { | ||
rangeQuery.exec() | ||
return rangeQuery.exec() | ||
.then(function (r) { | ||
@@ -273,11 +273,7 @@ observer.next(r.map(function (v) { return v[_this.shape.pk.name]; })); | ||
}; | ||
listener(); | ||
_this.db.observe(rangeQuery, listener); | ||
listener().then(function () { | ||
_this.db.observe(rangeQuery, listener); | ||
}); | ||
return function () { return _this.db.unobserve(rangeQuery, listener); }; | ||
}); | ||
/** | ||
* TODO 这里返回的 observable 第一个值和第二个值在它们的值不为空 | ||
* 的时候是重复的,也许有必要省去做优化;但不能简单 skip(1),因为 | ||
* 那样会导致不能推出空结果集。 | ||
*/ | ||
}; | ||
@@ -287,2 +283,22 @@ return Selector; | ||
exports.Selector = Selector; | ||
/** | ||
* Lovefield observe 出来的推送,第一次和第二次在它们的值不为空 | ||
* 的时候是重复的,这里做优化,省去重复;但不是简单的 skip(1),因为 | ||
* 那样会导致不能推出空结果集。详见:Lovefield issue#215 | ||
*/ | ||
var lfIssueFix = function (changes) { | ||
return changes | ||
.scan(function (ret, x) { | ||
ret.calledCount = ret.calledCount + 1; | ||
var calledCount = ret.calledCount; | ||
ret.shouldSkip = !!(x && x.length) && calledCount === 2; | ||
ret.result = x; | ||
return ret; | ||
}, { | ||
shouldSkip: false, | ||
calledCount: 0 | ||
}) | ||
.filter(function (x) { return !x.shouldSkip; }) | ||
.map(function (x) { return x.result; }); | ||
}; | ||
//# sourceMappingURL=Selector.js.map |
@@ -1,2 +0,2 @@ | ||
declare const _default: "0.9.10"; | ||
declare const _default: "0.9.11"; | ||
export default _default; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = '0.9.10'; | ||
exports.default = '0.9.11'; | ||
//# sourceMappingURL=version.js.map |
Sorry, the diff of this file is not supported yet
261969
4701
258