reactivedb
Advanced tools
Comparing version 0.10.4-alpha.14-diff to 0.10.4-alpha.15-diff2
@@ -68,2 +68,6 @@ /// <reference types="lovefield" /> | ||
} | ||
export interface ConcatInfo { | ||
length: number; | ||
consumed: boolean; | ||
} | ||
export interface Record { | ||
@@ -70,0 +74,0 @@ [property: string]: number; |
{ | ||
"name": "reactivedb", | ||
"version": "0.10.4-alpha.14-diff", | ||
"version": "0.10.4-alpha.15-diff2", | ||
"description": "Reactive ORM for Lovefield", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -78,2 +78,7 @@ import { Observable } from 'rxjs/Observable' | ||
export interface ConcatInfo { | ||
length: number | ||
consumed: boolean | ||
} | ||
export interface Record { | ||
@@ -80,0 +85,0 @@ [property: string]: number |
@@ -10,2 +10,4 @@ import { Observable } from 'rxjs/Observable' | ||
import { switchMap } from 'rxjs/operators/switchMap' | ||
import { startWith } from 'rxjs/operators/startWith' | ||
import { pairwise } from 'rxjs/operators/pairwise' | ||
import { take } from 'rxjs/operators/take' | ||
@@ -17,16 +19,6 @@ import { tap } from 'rxjs/operators/tap' | ||
import { TokenConsumed } from '../../exception/token' | ||
import { diff, Ops, OpsType, OpType } from '../../utils/diff' | ||
import { diff, Ops, OpsType, concatDiff } from '../../utils/diff' | ||
export type TraceResult<T> = Ops & { | ||
result: ReadonlyArray<T> | ||
} | ||
export type TraceResult<T> = Ops<T> | ||
function initialTraceResult<T>(list: ReadonlyArray<T>): TraceResult<T> { | ||
return { | ||
type: OpsType.Success, | ||
ops: list.map((_value, index) => ({ type: OpType.New, index })), | ||
result: list | ||
} | ||
} | ||
export type SelectorMeta<T> = Selector<T> | ProxySelector<T> | ||
@@ -42,5 +34,10 @@ | ||
private consume = () => { | ||
assert(!this.consumed, TokenConsumed()) | ||
this.consumed = true | ||
} | ||
constructor( | ||
selector$: Observable<SelectorMeta<T>>, | ||
private lastEmit?: ReadonlyArray<T> | ||
public concatConsumed = false | ||
) { | ||
@@ -51,9 +48,4 @@ this.selector$ = selector$.pipe( | ||
) | ||
this.lastEmit = lastEmit | ||
} | ||
setLastEmit(data: T[]) { | ||
this.lastEmit = data | ||
} | ||
map<K>(fn: OperatorFunction<T[], K[]>) { | ||
@@ -67,6 +59,4 @@ this.selector$ = this.selector$.pipe( | ||
values(): Observable<T[]> { | ||
assert(!this.consumed, TokenConsumed()) | ||
this.consumed = true | ||
return this.selector$.pipe( | ||
tap(this.consume), | ||
switchMap(s => s.values()), | ||
@@ -78,7 +68,5 @@ take(1) | ||
changes(): Observable<T[]> { | ||
assert(!this.consumed, TokenConsumed()) | ||
this.consumed = true | ||
return this.selector$.pipe( | ||
switchMap(s => s.changes()) | ||
tap(this.consume), | ||
switchMap(s => s.changes()), | ||
) | ||
@@ -88,12 +76,14 @@ } | ||
traces(pk?: string): Observable<TraceResult<T>> { | ||
return this.changes().pipe( | ||
map((result: T[]) => { | ||
if (!this.lastEmit) { | ||
return initialTraceResult(result) | ||
} | ||
const ops = diff(this.lastEmit, result, pk) | ||
return { result, ...ops } | ||
}), | ||
filter(({ type }) => type !== OpsType.ShouldSkip), | ||
tap(({ result }) => (this.lastEmit = result)), | ||
return this.selector$.pipe( | ||
tap(this.consume), | ||
switchMap(s => s.changes().pipe( | ||
startWith<T[]>([]), | ||
pairwise(), | ||
map(([lastEmit, result], i): TraceResult<T> => | ||
i === 0 && !(s instanceof ProxySelector) && s.concatInfo && (s.concatInfo.consumed || this.concatConsumed) | ||
? concatDiff(result, s.concatInfo!.length) | ||
: diff(lastEmit, result, pk) | ||
), | ||
filter(({ type }) => type !== OpsType.ShouldSkip), | ||
)), | ||
) | ||
@@ -105,3 +95,3 @@ } | ||
const newSelector$ = Observable.from(tokens).pipe( | ||
map(token => token.selector$.pipe(skipWhileProxySelector)), | ||
map((token) => token.selector$.pipe(skipWhileProxySelector)), | ||
combineAll<Observable<Selector<T>>, Selector<T>[]>(), | ||
@@ -113,3 +103,3 @@ map((r) => { | ||
) | ||
return new QueryToken<T>(newSelector$, this.lastEmit) | ||
return new QueryToken<T>(newSelector$, this.concatConsumed) | ||
} | ||
@@ -120,3 +110,3 @@ | ||
const newSelector$ = Observable.from(tokens).pipe( | ||
map(token => token.selector$.pipe(skipWhileProxySelector)), | ||
map((token) => token.selector$.pipe(skipWhileProxySelector)), | ||
combineAll<Observable<Selector<T>>, Selector<T>[]>(), | ||
@@ -128,3 +118,3 @@ map((r) => { | ||
) | ||
return new QueryToken<T>(newSelector$, this.lastEmit) | ||
return new QueryToken<T>(newSelector$) | ||
} | ||
@@ -131,0 +121,0 @@ |
@@ -12,2 +12,3 @@ import { Observer } from 'rxjs/Observer' | ||
import { switchMap } from 'rxjs/operators/switchMap' | ||
import { tap } from 'rxjs/operators/tap' | ||
import { async } from 'rxjs/scheduler/async' | ||
@@ -19,3 +20,3 @@ import * as lf from 'lovefield' | ||
import { PredicateProvider } from './PredicateProvider' | ||
import { ShapeMatcher, OrderInfo, StatementType } from '../../interface' | ||
import { ShapeMatcher, OrderInfo, StatementType, ConcatInfo } from '../../interface' | ||
import { mapFn } from './mapFn' | ||
@@ -40,5 +41,8 @@ | ||
}) | ||
const concatInfo = { length: meta.limit! - meta.skip!, consumed: meta.consumed } | ||
return new Selector( | ||
db, lselect, shape, predicateProvider, | ||
maxLimit.limit! + maxLimit.skip!, minSkip.skip, meta.orderDescriptions | ||
maxLimit.limit! + maxLimit.skip!, minSkip.skip, meta.orderDescriptions, | ||
concatInfo, | ||
) | ||
@@ -90,2 +94,6 @@ .map<U>(meta.mapFn) | ||
private consume = () => { | ||
this.consumed = true | ||
} | ||
private mapFn: (stream$: Observable<T[]>) => Observable<any[]> = mapFn | ||
@@ -193,3 +201,4 @@ | ||
private skip?: number, | ||
private orderDescriptions?: OrderInfo[] | ||
private orderDescriptions?: OrderInfo[], | ||
readonly concatInfo?: ConcatInfo, | ||
) { | ||
@@ -205,2 +214,3 @@ this.predicateProvider = this.normPredicateProvider(predicateProvider) | ||
values(): Observable<T[]> | never { | ||
let values$ | ||
if (typeof this.limit !== 'undefined' || typeof this.skip !== 'undefined') { | ||
@@ -210,6 +220,9 @@ const p = this.rangeQuery.exec() | ||
.then(pks => this.getValue(this.getQuery(this.inPKs(pks)))) | ||
return this.mapFn(Observable.fromPromise(p)) | ||
values$ = this.mapFn(Observable.fromPromise(p)) | ||
} else { | ||
return this.mapFn(Observable.fromPromise(this.getValue(this.getQuery()) as Promise<T[]>)) | ||
values$ = this.mapFn(Observable.fromPromise(this.getValue(this.getQuery()) as Promise<T[]>)) | ||
} | ||
return values$.pipe( | ||
tap(this.consume) | ||
) | ||
} | ||
@@ -236,2 +249,3 @@ | ||
assert(equal, tokenErrMsg.TokenConcatFailed()) | ||
console.info('concat', this.consumed) | ||
@@ -242,3 +256,6 @@ return Selector.concatFactory(this, ...selectors) | ||
changes(): Observable<T[]> | never { | ||
return this.mapFn(this.change$) | ||
return this.mapFn(this.change$).pipe( | ||
tap(this.consume), | ||
tap(() => console.info('consumed')) | ||
) | ||
} | ||
@@ -245,0 +262,0 @@ |
@@ -8,5 +8,10 @@ export enum OpType { | ||
export type Op = { | ||
type: OpType | ||
export type Op<T = any> = { | ||
type: OpType.Reuse | ||
index: number | ||
value?: undefined | ||
} | { | ||
type: OpType.New | ||
value: T | ||
index?: undefined | ||
} | ||
@@ -23,29 +28,34 @@ | ||
export type Ops = { | ||
type: OpsType | ||
ops: Op[] | ||
export type Ops<T = any> = { | ||
type: OpsType.Error | ||
result: ReadonlyArray<T> | ||
ops?: undefined | ||
message?: string | ||
} | { | ||
type: OpsType.Success | ||
ops: Op<T>[] | ||
result?: undefined | ||
message?: string | ||
} | { | ||
type: OpsType.ShouldSkip | ||
ops?: undefined | ||
result?: undefined | ||
message?: string | ||
} | ||
// as an example, use diff to patch data | ||
export const patch = <T>(ops: ReadonlyArray<Op>, oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>) => { | ||
if (!oldList.length) { | ||
return newList | ||
} | ||
return newList.map((data, i) => { | ||
const op = ops[i] | ||
export const patch = <T>(ops: ReadonlyArray<Op>, oldList: ReadonlyArray<T>) => { | ||
return ops.map(op => { | ||
if (op.type === OpType.Reuse) { | ||
return oldList[op.index] | ||
} else { | ||
return op.value | ||
} | ||
return data | ||
}) | ||
} | ||
export const getPatchResult = <T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, ops: Ops): ReadonlyArray<T> => { | ||
export const getPatchResult = <T>(oldList: ReadonlyArray<T>, ops: Ops): ReadonlyArray<T> => { | ||
switch (ops.type) { | ||
case OpsType.Error: | ||
return newList | ||
return ops.result | ||
case OpsType.ShouldSkip: | ||
@@ -55,3 +65,3 @@ return oldList | ||
default: | ||
return patch(ops.ops, oldList, newList) | ||
return patch(ops.ops, oldList) | ||
} | ||
@@ -76,3 +86,3 @@ } | ||
for (let i = length; i-- !== 0; ) { | ||
for (let i = length; i-- !== 0;) { | ||
if (!fastEqual(left[i], right[i])) { | ||
@@ -108,3 +118,3 @@ return false | ||
for (let k = LeftLen; k-- !== 0; ) { | ||
for (let k = LeftLen; k-- !== 0;) { | ||
if (!right.hasOwnProperty(keys[k])) { | ||
@@ -115,3 +125,3 @@ return false | ||
for (let j = LeftLen; j-- !== 0; ) { | ||
for (let j = LeftLen; j-- !== 0;) { | ||
const key = keys[j] | ||
@@ -129,3 +139,3 @@ if (!fastEqual(left[key], right[key])) { | ||
export function diff<T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, pk = '_id'): Ops { | ||
export function diff<T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, pk = '_id'): Ops<T> { | ||
const prev = oldList | ||
@@ -137,3 +147,3 @@ const curr = newList | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: `cannot compare non-list object`, | ||
@@ -149,3 +159,3 @@ } | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: `cannot find pk: ${pk} at prev.${i}`, | ||
@@ -157,3 +167,3 @@ } | ||
const ret: Op[] = [] | ||
const ret: Op<T>[] = [] | ||
let reused = 0 | ||
@@ -166,3 +176,3 @@ | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: `cannot find pk: ${pk} at curr.${k}`, | ||
@@ -175,5 +185,5 @@ } | ||
if (prevIndex !== undefined) { | ||
const isEqual = fastEqual((curr as any)[k], (prev as any)[prevIndex]) | ||
const isEqual = fastEqual(curr[k], prev[prevIndex]) | ||
// if equal then reuse the previous data otherwise use the new data | ||
const op: Op = isEqual ? { type: OpType.Reuse, index: prevIndex } : { type: OpType.New, index: k } | ||
const op: Op<T> = isEqual ? { type: OpType.Reuse, index: prevIndex } : { type: OpType.New, value: curr[k] } | ||
@@ -185,3 +195,3 @@ if (prevIndex === k && isEqual) { | ||
} else { | ||
ret.push({ type: OpType.New, index: k }) | ||
ret.push({ type: OpType.New, value: curr[k] }) | ||
} | ||
@@ -191,6 +201,16 @@ } | ||
const arrayIsSame = reused === curr.length && prev.length === curr.length | ||
return arrayIsSame | ||
? { type: OpsType.ShouldSkip } | ||
: { type: OpsType.Success, ops: ret } | ||
} | ||
export const concatDiff = <T>(newList: ReadonlyArray<T>, concatLength: number) => { | ||
return { | ||
type: arrayIsSame ? OpsType.ShouldSkip : OpsType.Success, | ||
ops: ret, | ||
} | ||
type: OpsType.Success, | ||
ops: newList.map((value, index) => { | ||
return index >= concatLength | ||
? { type: OpType.New, value } | ||
: { type: OpType.Reuse, index } | ||
}) | ||
} as Ops<T> | ||
} |
@@ -1,1 +0,2 @@ | ||
export default '0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-lazyassert' | ||
/* tslint:disable */ | ||
export default '0.10.4-alpha.15-diff2' |
@@ -6,12 +6,10 @@ import { Observable } from 'rxjs/Observable'; | ||
import { Ops } from '../../utils/diff'; | ||
export declare type TraceResult<T> = Ops & { | ||
result: ReadonlyArray<T>; | ||
}; | ||
export declare type TraceResult<T> = Ops<T>; | ||
export declare type SelectorMeta<T> = Selector<T> | ProxySelector<T>; | ||
export declare class QueryToken<T> { | ||
private lastEmit; | ||
concatConsumed: boolean; | ||
selector$: Observable<SelectorMeta<T>>; | ||
private consumed; | ||
constructor(selector$: Observable<SelectorMeta<T>>, lastEmit?: ReadonlyArray<T> | undefined); | ||
setLastEmit(data: T[]): void; | ||
private consume; | ||
constructor(selector$: Observable<SelectorMeta<T>>, concatConsumed?: boolean); | ||
map<K>(fn: OperatorFunction<T[], K[]>): QueryToken<K>; | ||
@@ -18,0 +16,0 @@ values(): Observable<T[]>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
var Observable_1 = require("rxjs/Observable"); | ||
@@ -12,2 +11,4 @@ var combineAll_1 = require("rxjs/operators/combineAll"); | ||
var switchMap_1 = require("rxjs/operators/switchMap"); | ||
var startWith_1 = require("rxjs/operators/startWith"); | ||
var pairwise_1 = require("rxjs/operators/pairwise"); | ||
var take_1 = require("rxjs/operators/take"); | ||
@@ -19,20 +20,15 @@ var tap_1 = require("rxjs/operators/tap"); | ||
var diff_1 = require("../../utils/diff"); | ||
function initialTraceResult(list) { | ||
return { | ||
type: diff_1.OpsType.Success, | ||
ops: list.map(function (_value, index) { return ({ type: diff_1.OpType.New, index: index }); }), | ||
result: list | ||
}; | ||
} | ||
var skipWhileProxySelector = skipWhile_1.skipWhile(function (v) { return v instanceof ProxySelector_1.ProxySelector; }); | ||
var QueryToken = /** @class */ (function () { | ||
function QueryToken(selector$, lastEmit) { | ||
this.lastEmit = lastEmit; | ||
function QueryToken(selector$, concatConsumed) { | ||
if (concatConsumed === void 0) { concatConsumed = false; } | ||
var _this = this; | ||
this.concatConsumed = concatConsumed; | ||
this.consumed = false; | ||
this.consume = function () { | ||
assert_1.assert(!_this.consumed, token_1.TokenConsumed()); | ||
_this.consumed = true; | ||
}; | ||
this.selector$ = selector$.pipe(publishReplay_1.publishReplay(1), refCount_1.refCount()); | ||
this.lastEmit = lastEmit; | ||
} | ||
QueryToken.prototype.setLastEmit = function (data) { | ||
this.lastEmit = data; | ||
}; | ||
QueryToken.prototype.map = function (fn) { | ||
@@ -43,26 +39,18 @@ this.selector$ = this.selector$.pipe(tap_1.tap(function (selector) { return selector.map(fn); })); | ||
QueryToken.prototype.values = function () { | ||
assert_1.assert(!this.consumed, token_1.TokenConsumed()); | ||
this.consumed = true; | ||
return this.selector$.pipe(switchMap_1.switchMap(function (s) { return s.values(); }), take_1.take(1)); | ||
return this.selector$.pipe(tap_1.tap(this.consume), switchMap_1.switchMap(function (s) { return s.values(); }), take_1.take(1)); | ||
}; | ||
QueryToken.prototype.changes = function () { | ||
assert_1.assert(!this.consumed, token_1.TokenConsumed()); | ||
this.consumed = true; | ||
return this.selector$.pipe(switchMap_1.switchMap(function (s) { return s.changes(); })); | ||
return this.selector$.pipe(tap_1.tap(this.consume), switchMap_1.switchMap(function (s) { return s.changes(); })); | ||
}; | ||
QueryToken.prototype.traces = function (pk) { | ||
var _this = this; | ||
return this.changes().pipe(map_1.map(function (result) { | ||
if (!_this.lastEmit) { | ||
return initialTraceResult(result); | ||
} | ||
var ops = diff_1.diff(_this.lastEmit, result, pk); | ||
return tslib_1.__assign({ result: result }, ops); | ||
return this.selector$.pipe(tap_1.tap(this.consume), switchMap_1.switchMap(function (s) { return s.changes().pipe(startWith_1.startWith([]), pairwise_1.pairwise(), map_1.map(function (_a, i) { | ||
var lastEmit = _a[0], result = _a[1]; | ||
return i === 0 && !(s instanceof ProxySelector_1.ProxySelector) && s.concatInfo && (s.concatInfo.consumed || _this.concatConsumed) | ||
? diff_1.concatDiff(result, s.concatInfo.length) | ||
: diff_1.diff(lastEmit, result, pk); | ||
}), filter_1.filter(function (_a) { | ||
var type = _a.type; | ||
return type !== diff_1.OpsType.ShouldSkip; | ||
}), tap_1.tap(function (_a) { | ||
var result = _a.result; | ||
return (_this.lastEmit = result); | ||
})); | ||
})); })); | ||
}; | ||
@@ -80,3 +68,3 @@ QueryToken.prototype.concat = function () { | ||
})); | ||
return new QueryToken(newSelector$, this.lastEmit); | ||
return new QueryToken(newSelector$, this.concatConsumed); | ||
}; | ||
@@ -94,3 +82,3 @@ QueryToken.prototype.combine = function () { | ||
})); | ||
return new QueryToken(newSelector$, this.lastEmit); | ||
return new QueryToken(newSelector$); | ||
}; | ||
@@ -97,0 +85,0 @@ QueryToken.prototype.toString = function () { |
@@ -6,3 +6,3 @@ /// <reference types="lovefield" /> | ||
import { PredicateProvider } from './PredicateProvider'; | ||
import { ShapeMatcher, OrderInfo } from '../../interface'; | ||
import { ShapeMatcher, OrderInfo, ConcatInfo } from '../../interface'; | ||
export declare class Selector<T> { | ||
@@ -16,5 +16,7 @@ db: lf.Database; | ||
private orderDescriptions; | ||
readonly concatInfo: ConcatInfo | undefined; | ||
private static concatFactory<U>(...metaDatas); | ||
private static combineFactory<U>(...metaDatas); | ||
private static stringifyOrder(orderInfo); | ||
private consume; | ||
private mapFn; | ||
@@ -29,3 +31,3 @@ select: string; | ||
private normPredicateProvider(pp?); | ||
constructor(db: lf.Database, lselect: lf.query.Select, shape: ShapeMatcher, predicateProvider?: PredicateProvider<T> | undefined, limit?: number | undefined, skip?: number | undefined, orderDescriptions?: OrderInfo[] | undefined); | ||
constructor(db: lf.Database, lselect: lf.query.Select, shape: ShapeMatcher, predicateProvider?: PredicateProvider<T> | undefined, limit?: number | undefined, skip?: number | undefined, orderDescriptions?: OrderInfo[] | undefined, concatInfo?: ConcatInfo | undefined); | ||
toString(): string; | ||
@@ -32,0 +34,0 @@ values(): Observable<T[]> | never; |
@@ -12,2 +12,3 @@ "use strict"; | ||
var switchMap_1 = require("rxjs/operators/switchMap"); | ||
var tap_1 = require("rxjs/operators/tap"); | ||
var async_1 = require("rxjs/scheduler/async"); | ||
@@ -21,3 +22,4 @@ var lf = require("lovefield"); | ||
var Selector = /** @class */ (function () { | ||
function Selector(db, lselect, shape, predicateProvider, limit, skip, orderDescriptions) { | ||
function Selector(db, lselect, shape, predicateProvider, limit, skip, orderDescriptions, concatInfo) { | ||
var _this = this; | ||
this.db = db; | ||
@@ -30,2 +32,6 @@ this.lselect = lselect; | ||
this.orderDescriptions = orderDescriptions; | ||
this.concatInfo = concatInfo; | ||
this.consume = function () { | ||
_this.consumed = true; | ||
}; | ||
this.mapFn = mapFn_1.mapFn; | ||
@@ -54,3 +60,4 @@ this._change$ = null; | ||
}); | ||
return new Selector(db, lselect, shape, predicateProvider, maxLimit.limit + maxLimit.skip, minSkip.skip, meta.orderDescriptions) | ||
var concatInfo = { length: meta.limit - meta.skip, consumed: meta.consumed }; | ||
return new Selector(db, lselect, shape, predicateProvider, maxLimit.limit + maxLimit.skip, minSkip.skip, meta.orderDescriptions, concatInfo) | ||
.map(meta.mapFn); | ||
@@ -180,2 +187,3 @@ }; | ||
var _this = this; | ||
var values$; | ||
if (typeof this.limit !== 'undefined' || typeof this.skip !== 'undefined') { | ||
@@ -185,7 +193,8 @@ var p = this.rangeQuery.exec() | ||
.then(function (pks) { return _this.getValue(_this.getQuery(_this.inPKs(pks))); }); | ||
return this.mapFn(Observable_1.Observable.fromPromise(p)); | ||
values$ = this.mapFn(Observable_1.Observable.fromPromise(p)); | ||
} | ||
else { | ||
return this.mapFn(Observable_1.Observable.fromPromise(this.getValue(this.getQuery()))); | ||
values$ = this.mapFn(Observable_1.Observable.fromPromise(this.getValue(this.getQuery()))); | ||
} | ||
return values$.pipe(tap_1.tap(this.consume)); | ||
}; | ||
@@ -215,6 +224,7 @@ Selector.prototype.combine = function () { | ||
utils_1.assert(equal, exception_1.tokenErrMsg.TokenConcatFailed()); | ||
console.info('concat', this.consumed); | ||
return Selector.concatFactory.apply(Selector, [this].concat(selectors)); | ||
}; | ||
Selector.prototype.changes = function () { | ||
return this.mapFn(this.change$); | ||
return this.mapFn(this.change$).pipe(tap_1.tap(this.consume), tap_1.tap(function () { return console.info('consumed'); })); | ||
}; | ||
@@ -221,0 +231,0 @@ Selector.prototype.map = function (fn) { |
@@ -5,5 +5,10 @@ export declare enum OpType { | ||
} | ||
export declare type Op = { | ||
type: OpType; | ||
export declare type Op<T = any> = { | ||
type: OpType.Reuse; | ||
index: number; | ||
value?: undefined; | ||
} | { | ||
type: OpType.New; | ||
value: T; | ||
index?: undefined; | ||
}; | ||
@@ -15,9 +20,21 @@ export declare enum OpsType { | ||
} | ||
export declare type Ops = { | ||
type: OpsType; | ||
ops: Op[]; | ||
export declare type Ops<T = any> = { | ||
type: OpsType.Error; | ||
result: ReadonlyArray<T>; | ||
ops?: undefined; | ||
message?: string; | ||
} | { | ||
type: OpsType.Success; | ||
ops: Op<T>[]; | ||
result?: undefined; | ||
message?: string; | ||
} | { | ||
type: OpsType.ShouldSkip; | ||
ops?: undefined; | ||
result?: undefined; | ||
message?: string; | ||
}; | ||
export declare const patch: <T>(ops: ReadonlyArray<Op>, oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>) => ReadonlyArray<T>; | ||
export declare const getPatchResult: <T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, ops: Ops) => ReadonlyArray<T>; | ||
export declare function diff<T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, pk?: string): Ops; | ||
export declare const patch: <T>(ops: ReadonlyArray<Op<any>>, oldList: ReadonlyArray<T>) => any[]; | ||
export declare const getPatchResult: <T>(oldList: ReadonlyArray<T>, ops: Ops<any>) => ReadonlyArray<T>; | ||
export declare function diff<T>(oldList: ReadonlyArray<T>, newList: ReadonlyArray<T>, pk?: string): Ops<T>; | ||
export declare const concatDiff: <T>(newList: ReadonlyArray<T>, concatLength: number) => Ops<T>; |
@@ -20,18 +20,16 @@ "use strict"; | ||
// as an example, use diff to patch data | ||
exports.patch = function (ops, oldList, newList) { | ||
if (!oldList.length) { | ||
return newList; | ||
} | ||
return newList.map(function (data, i) { | ||
var op = ops[i]; | ||
exports.patch = function (ops, oldList) { | ||
return ops.map(function (op) { | ||
if (op.type === OpType.Reuse) { | ||
return oldList[op.index]; | ||
} | ||
return data; | ||
else { | ||
return op.value; | ||
} | ||
}); | ||
}; | ||
exports.getPatchResult = function (oldList, newList, ops) { | ||
exports.getPatchResult = function (oldList, ops) { | ||
switch (ops.type) { | ||
case OpsType.Error: | ||
return newList; | ||
return ops.result; | ||
case OpsType.ShouldSkip: | ||
@@ -41,3 +39,3 @@ return oldList; | ||
default: | ||
return exports.patch(ops.ops, oldList, newList); | ||
return exports.patch(ops.ops, oldList); | ||
} | ||
@@ -102,3 +100,3 @@ }; | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: "cannot compare non-list object", | ||
@@ -113,3 +111,3 @@ }; | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: "cannot find pk: " + pk + " at prev." + i, | ||
@@ -127,3 +125,3 @@ }; | ||
type: OpsType.Error, | ||
ops: [], | ||
result: newList, | ||
message: "cannot find pk: " + pk + " at curr." + k, | ||
@@ -136,3 +134,3 @@ }; | ||
// if equal then reuse the previous data otherwise use the new data | ||
var op = isEqual ? { type: OpType.Reuse, index: prevIndex } : { type: OpType.New, index: k }; | ||
var op = isEqual ? { type: OpType.Reuse, index: prevIndex } : { type: OpType.New, value: curr[k] }; | ||
if (prevIndex === k && isEqual) { | ||
@@ -144,12 +142,21 @@ reused++; | ||
else { | ||
ret.push({ type: OpType.New, index: k }); | ||
ret.push({ type: OpType.New, value: curr[k] }); | ||
} | ||
} | ||
var arrayIsSame = reused === curr.length && prev.length === curr.length; | ||
return arrayIsSame | ||
? { type: OpsType.ShouldSkip } | ||
: { type: OpsType.Success, ops: ret }; | ||
} | ||
exports.diff = diff; | ||
exports.concatDiff = function (newList, concatLength) { | ||
return { | ||
type: arrayIsSame ? OpsType.ShouldSkip : OpsType.Success, | ||
ops: ret, | ||
type: OpsType.Success, | ||
ops: newList.map(function (value, index) { | ||
return index >= concatLength | ||
? { type: OpType.New, value: value } | ||
: { type: OpType.Reuse, index: index }; | ||
}) | ||
}; | ||
} | ||
exports.diff = diff; | ||
}; | ||
//# sourceMappingURL=diff.js.map |
@@ -1,2 +0,2 @@ | ||
declare const _default: "0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-lazyassert"; | ||
declare const _default: "0.10.4-alpha.15-diff2"; | ||
export default _default; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = '0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-alpha0.10.4-alpha.14-diff-alpha0.10.4-alpha.14-diff-diff-diff-lazyassert'; | ||
/* tslint:disable */ | ||
exports.default = '0.10.4-alpha.15-diff2'; | ||
//# sourceMappingURL=version.js.map |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
299342
5378