reactive-di
Advanced tools
Comparing version 3.1.1 to 3.1.2
@@ -96,10 +96,5 @@ 'use strict'; | ||
var newVal = this._create(this._proto.cached || this._proto.get(), this._argVals || []); | ||
// copy old computed state, not setted in constructor (via setters) to new object | ||
var src = this.cachedSrc; | ||
if (this._hook && this.cachedSrc && !this._hook.shouldUpdate(newVal, this.cachedSrc)) { | ||
return this._cachedProxy; | ||
} | ||
this.cachedSrc = newVal; | ||
// copy old computed state, not setted in constructor (via setters) to new object | ||
var src = this._cachedProxy; | ||
if (src) { | ||
@@ -112,4 +107,9 @@ for (var k in src) { | ||
} | ||
if (this._hook && !this._hook.shouldUpdate(newVal, src)) { | ||
return this._cachedProxy; | ||
} | ||
} | ||
this.cachedSrc = newVal; | ||
if (this._isWrapped) { | ||
@@ -116,0 +116,0 @@ if (!this._cachedProxy) { |
@@ -163,3 +163,10 @@ 'use strict'; | ||
} | ||
this._lastState = this._parent.cached; | ||
var parent = this._parent; | ||
if (!parent.cached) { | ||
parent.pull(); | ||
if (!parent.cached) { | ||
throw new Error(this._parent.displayName + '.cached is null'); | ||
} | ||
} | ||
this._lastState = parent.cached; | ||
try { | ||
@@ -199,4 +206,6 @@ return (this._proto.cached || this._proto.get())(this.cached, this._lastState, this); | ||
try { | ||
if (this._hook) { | ||
this._hook.willMount(); | ||
var hook = this._hook; | ||
if (hook) { | ||
hook.resolve(); | ||
hook.willMount(); | ||
} | ||
@@ -203,0 +212,0 @@ this._parent.willMount(); |
@@ -41,2 +41,3 @@ 'use strict'; | ||
this.binder = c.binder; | ||
this.Updater = c.Updater; | ||
this.notifier = c.notifier; | ||
@@ -43,0 +44,0 @@ this.defaultErrorComponent = c.defaultErrorComponent; |
@@ -22,2 +22,6 @@ 'use strict'; | ||
var _Updater = require('./source/Updater'); | ||
var _Updater2 = _interopRequireDefault(_Updater); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -39,3 +43,4 @@ | ||
binder: new _RelationBinder2.default(values), | ||
protoFactory: null | ||
protoFactory: null, | ||
Updater: opts.updater || _Updater2.default | ||
}; | ||
@@ -42,0 +47,0 @@ if (opts.debug) { |
@@ -43,2 +43,3 @@ 'use strict'; | ||
this._prev = null; | ||
this._inHook = false; | ||
this._notifier = context.notifier; | ||
@@ -104,3 +105,5 @@ } | ||
notifier.trace = this.displayName + '.willMount'; | ||
notifier.opId++;hook.willMount(target); | ||
notifier.opId++; | ||
this._inHook = true;hook.willMount(target); | ||
this._inHook = false; | ||
notifier.trace = oldTrace; | ||
@@ -118,7 +121,9 @@ } | ||
var hook = this.cached || this._get(); | ||
if (hook.willUnmount) { | ||
if (hook.willUnmount && !this._inWillMount) { | ||
var notifier = this._notifier; | ||
var oldTrace = notifier.trace; | ||
notifier.trace = this.displayName + '.willUnmount'; | ||
notifier.opId++;hook.willUnmount(target); | ||
notifier.opId++; | ||
this._inHook = true;hook.willUnmount(target); | ||
this._inHook = false; | ||
notifier.trace = oldTrace; | ||
@@ -134,7 +139,9 @@ } | ||
} | ||
if (hook.willUpdate) { | ||
if (hook.willUpdate && !this._inHook) { | ||
var notifier = this._notifier; | ||
var oldTrace = notifier.trace; | ||
notifier.trace = this.displayName + '.willUpdate'; | ||
notifier.opId++;hook.willUpdate(target); | ||
notifier.opId++; | ||
this._inHook = true;hook.willUpdate(target); | ||
this._inHook = false; | ||
notifier.trace = oldTrace; | ||
@@ -157,3 +164,5 @@ } | ||
notifier.trace = this.displayName + '.willUnmount'; | ||
notifier.opId++;hook.willUnmount(target); | ||
notifier.opId++; | ||
this._inHook = true;hook.willUnmount(target); | ||
this._inHook = false; | ||
notifier.trace = oldTrace; | ||
@@ -171,11 +180,8 @@ } | ||
var oldTrace = notifier.trace; | ||
notifier.opId++; | ||
if (hook.willUnmount) { | ||
notifier.trace = this.displayName + '.willUnmount';hook.willUnmount(target); | ||
this._inHook = true; | ||
if (hook.selfUpdate) { | ||
notifier.trace = this.displayName + '.selfUpdate';hook.selfUpdate(target); | ||
} | ||
if (hook.willMount) { | ||
notifier.trace = this.displayName + '.willMount';hook.willMount(target); | ||
} | ||
notifier.trace = oldTrace; | ||
this.context.notifier.flush(); | ||
this._inHook = false; | ||
}; | ||
@@ -182,0 +188,0 @@ |
@@ -43,15 +43,20 @@ 'use strict'; | ||
} | ||
var consumers = this._consumers; | ||
// consumer.pull can recursively run Transact.end, protect from this | ||
this._consumers = []; | ||
var upd = []; | ||
for (var i = 0, l = consumers.length; i < l; i++) { | ||
var consumer = consumers[i]; | ||
if (!consumer.cached && !consumer.closed) { | ||
var updater = consumer.pull(); | ||
if (updater) { | ||
upd.push(updater); | ||
do { | ||
var consumers = this._consumers; | ||
// consumer.pull can recursively run Transact.end, protect from this | ||
this._consumers = []; | ||
for (var i = 0, l = consumers.length; i < l; i++) { | ||
var consumer = consumers[i]; | ||
if (!consumer.cached && !consumer.closed) { | ||
var updater = consumer.pull(); | ||
if (updater) { | ||
// updater.forceUpdate() | ||
upd.push(updater); | ||
} | ||
} | ||
} | ||
} while (this._consumers.length > 0); | ||
if (this.logger) { | ||
this.logger.get().onRender(upd); | ||
} | ||
@@ -58,0 +63,0 @@ |
@@ -28,5 +28,5 @@ 'use strict'; | ||
var _Updater = require('./Updater'); | ||
var _Promisable = require('./Promisable'); | ||
var _Updater2 = _interopRequireDefault(_Updater); | ||
var _Promisable2 = _interopRequireDefault(_Promisable); | ||
@@ -71,2 +71,3 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
this._eventSetter = null; | ||
this._promisable = null; | ||
} | ||
@@ -187,2 +188,14 @@ | ||
Source.prototype._getPromisable = function _getPromisable() { | ||
if (!this._promisable) { | ||
this._promisable = new _Promisable2.default(); | ||
} | ||
return this._promisable; | ||
}; | ||
Source.prototype.promise = function promise() { | ||
return this._getPromisable().promise; | ||
}; | ||
Source.prototype.merge = function merge(v) { | ||
@@ -197,3 +210,3 @@ if (!this.cached) { | ||
Source.prototype.update = function update(updaterPayload) { | ||
var updater = new _Updater2.default(updaterPayload, this, this.context.notifier); | ||
var updater = new this.context.Updater(updaterPayload, this, this.getStatus(), this._getPromisable(), this.context.notifier); | ||
updater.run(); | ||
@@ -222,3 +235,2 @@ | ||
} | ||
var context = this.context; | ||
var computeds = this.computeds.items; | ||
@@ -228,3 +240,3 @@ for (var i = 0, l = computeds.length; i < l; i++) { | ||
} | ||
context.notifier.notify(this.consumers.items, this.displayName, this.cached, v); | ||
this.context.notifier.notify(this.consumers.items, this.displayName, this.cached, v); | ||
this.cached = v; | ||
@@ -231,0 +243,0 @@ }; |
@@ -14,14 +14,4 @@ 'use strict'; | ||
this.error = opts ? opts.error || null : null; | ||
this.promise = opts ? opts.promise || this._createPromise() : this._createPromise(); | ||
} | ||
SourceStatus.prototype._createPromise = function _createPromise() { | ||
var _this = this; | ||
return new Promise(function (resolve, reject) { | ||
_this._resolve = resolve; | ||
_this._reject = reject; | ||
}); | ||
}; | ||
SourceStatus.prototype.isEqual = function isEqual(status) { | ||
@@ -28,0 +18,0 @@ return status.complete && this.complete || status.pending && this.pending || !!status.error && status.error === this.error; |
@@ -18,3 +18,3 @@ 'use strict'; | ||
var completeObj = { complete: true, pending: false, error: null, promise: null }; | ||
var completeObj = { complete: true, pending: false, error: null }; | ||
@@ -47,12 +47,14 @@ var RecoverableError = exports.RecoverableError = function (_Err) { | ||
var Updater = function () { | ||
function Updater(updater, source, notifier) { | ||
function Updater(updater, source, status, promisable, notifier) { | ||
_classCallCheck(this, Updater); | ||
this._source = source; | ||
this._status = status; | ||
this._notifier = notifier; | ||
this._updater = updater; | ||
this._notifier = notifier; | ||
this._promisable = promisable; | ||
this._isCanceled = false; | ||
this._v = null; | ||
this.displayName = source.displayName; | ||
this._id = ++notifier.opId; | ||
this._id = ++this._notifier.opId; | ||
} | ||
@@ -64,3 +66,3 @@ | ||
var updater = this._updater; | ||
var status = this._source.getStatus(); | ||
var status = this._status; | ||
var pending = { | ||
@@ -127,5 +129,3 @@ complete: false, | ||
notifier.onError(error, this._source.displayName); | ||
var status = this._source.getStatus(); | ||
var statusValue = status.cached || status.get(); | ||
status.merge({ error: error, complete: false, pending: false, promise: null }); | ||
this._status.merge({ error: error, complete: false, pending: false }); | ||
var observer = this._updater; | ||
@@ -135,3 +135,3 @@ if (observer && observer.error) { | ||
} | ||
statusValue._reject(error); | ||
this._promisable.reject(error); | ||
notifier.opId = oldId; | ||
@@ -152,8 +152,7 @@ notifier.trace = oldTrace; | ||
var source = this._source; | ||
var status = source.getStatus(); | ||
var statusValue = status.cached || status.get(); | ||
var status = this._status; | ||
status.merge(completeObj); | ||
if (v) { | ||
this._source.merge(v); | ||
source.merge(v); | ||
} | ||
@@ -164,3 +163,3 @@ var observer = this._updater; | ||
} | ||
statusValue._resolve(v || this._v); | ||
this._promisable.resolve(v || this._v); | ||
notifier.opId = oldId; | ||
@@ -167,0 +166,0 @@ notifier.trace = oldTrace; |
{ | ||
"name": "reactive-di", | ||
"version": "3.1.1", | ||
"version": "3.1.2", | ||
"description": "Reactive dependency injection", | ||
@@ -9,3 +9,3 @@ "publishConfig": { | ||
"config": { | ||
"builddir": "." | ||
"dest": "./out" | ||
}, | ||
@@ -18,4 +18,4 @@ "scripts": { | ||
"update": "ncu -ua && npm install", | ||
"clean": "rm -rf $npm_package_config_builddir/dist", | ||
"build": "npm run clean && babel src --ignore=__tests__ --source-maps --out-dir $npm_package_config_builddir/dist", | ||
"clean": "rm -rf dist", | ||
"build": "npm run clean && babel src --ignore=__tests__ --source-maps --out-dir dist", | ||
"build.dep": "npm-helpers/build-deps.sh", | ||
@@ -28,4 +28,5 @@ "build.dev": "npm run build -- --watch", | ||
"test.dev": "mocha --growl --watch", | ||
"analyze": "webpack --config examples/app/webpack.config.es5.js --json | webpack-bundle-size-analyzer", | ||
"start": "webpack-dev-server --config examples/app/webpack.config.es5.js --hot --history-api-fallback --inline" | ||
"analyze": "webpack --config examples/app/webpack.config.js --json | webpack-bundle-size-analyzer", | ||
"start": "webpack-dev-server --config examples/app/webpack.config.babel.js --hot --history-api-fallback --inline", | ||
"watch": "chokidar --initial -d 2000 -t 1000 'src/**/*.js' -c 'npm run build && cp -rvf *.js src dist $npm_package_config_dest/node_modules/reactive-di'" | ||
}, | ||
@@ -79,2 +80,3 @@ "author": "Stefan Zerkalica <zerkalica@gmail.com>", | ||
"babel-preset-stage-0": "^6.22.0", | ||
"chokidar-cli": "^1.2.0", | ||
"eslint-config-airplus": "^2.0.10", | ||
@@ -81,0 +83,0 @@ "flow-bin": "^0.39.0", |
@@ -57,2 +57,10 @@ # Reactive DI [![Build Status](https://secure.travis-ci.org/zerkalica/reactive-di.png)](http://travis-ci.org/zerkalica/reactive-di) | ||
## Debug | ||
Build rdi and copy to ../app-project/node_modules/reactive-di | ||
``` | ||
npm run watch --reactive-di:dest=../app-project | ||
``` | ||
## Basics | ||
@@ -59,0 +67,0 @@ |
// @flow | ||
import type {IArg, IGetable} from './utils/resolveArgs' | ||
import type {ISource, IStatus} from './source/interfaces' | ||
import type {IControllable, ISource, IStatus} from './source/interfaces' | ||
import type {INotifier, IHook} from './hook/interfaces' | ||
@@ -45,2 +45,3 @@ import type {IComputed} from './computed/interfaces' | ||
protoFactory: ?IContext; | ||
Updater: Class<IControllable>; | ||
} | ||
@@ -47,0 +48,0 @@ |
@@ -114,10 +114,5 @@ // @flow | ||
const newVal = this._create(this._proto.cached || this._proto.get(), this._argVals || []) | ||
// copy old computed state, not setted in constructor (via setters) to new object | ||
const src = this.cachedSrc | ||
if (this._hook && this.cachedSrc && !this._hook.shouldUpdate(newVal, this.cachedSrc)) { | ||
return this._cachedProxy | ||
} | ||
this.cachedSrc = newVal | ||
// copy old computed state, not setted in constructor (via setters) to new object | ||
const src = this._cachedProxy | ||
if (src) { | ||
@@ -129,4 +124,9 @@ for (const k in src) { // eslint-disable-line | ||
} | ||
if (this._hook && !this._hook.shouldUpdate(newVal, src)) { | ||
return this._cachedProxy | ||
} | ||
} | ||
this.cachedSrc = newVal | ||
if (this._isWrapped) { | ||
@@ -133,0 +133,0 @@ if (!this._cachedProxy) { |
@@ -24,3 +24,6 @@ // @flow | ||
interface IParent<Props, State> { | ||
displayName: string; | ||
cached: ?State; | ||
pull(): any; | ||
willMount(): void; | ||
@@ -224,3 +227,10 @@ willUnmount(): void; | ||
} | ||
this._lastState = this._parent.cached | ||
const parent = this._parent | ||
if (!parent.cached) { | ||
parent.pull() | ||
if (!parent.cached) { | ||
throw new Error(`${this._parent.displayName}.cached is null`) | ||
} | ||
} | ||
this._lastState = parent.cached | ||
try { | ||
@@ -264,4 +274,6 @@ return (this._proto.cached || this._proto.get())( | ||
try { | ||
if (this._hook) { | ||
this._hook.willMount() | ||
const hook = this._hook | ||
if (hook) { | ||
hook.resolve() | ||
hook.willMount() | ||
} | ||
@@ -268,0 +280,0 @@ this._parent.willMount() |
@@ -7,3 +7,3 @@ // @flow | ||
import type {ISource, IStatus} from './source/interfaces' | ||
import type {IControllable, ISource, IStatus} from './source/interfaces' | ||
import Source from './source/Source' | ||
@@ -36,2 +36,4 @@ import Status from './source/Status' | ||
Updater: Class<IControllable>; | ||
_parents: IContext[] | ||
@@ -51,2 +53,3 @@ _context: IStaticContext<Component, Element> | ||
this.binder = c.binder | ||
this.Updater = c.Updater | ||
this.notifier = c.notifier | ||
@@ -53,0 +56,0 @@ this.defaultErrorComponent = c.defaultErrorComponent |
@@ -13,3 +13,5 @@ // @flow | ||
import Di from './Di' | ||
import type {ILogger} from './interfaces' | ||
import type {ILogger} from './hook/interfaces' | ||
import type {IControllable} from './source/interfaces' | ||
import Updater from './source/Updater' | ||
@@ -23,2 +25,3 @@ export type IOpts<Component, Element> = { | ||
logger?: Class<ILogger>; | ||
updater?: Class<IControllable>; | ||
} | ||
@@ -39,3 +42,4 @@ | ||
binder: new RelationBinder(values), | ||
protoFactory: null | ||
protoFactory: null, | ||
Updater: opts.updater || Updater | ||
} | ||
@@ -42,0 +46,0 @@ if (opts.debug) { |
@@ -38,2 +38,3 @@ // @flow | ||
_notifier: INotifier | ||
_inHook: boolean | ||
@@ -64,2 +65,3 @@ constructor( | ||
this._prev = null | ||
this._inHook = false | ||
this._notifier = context.notifier | ||
@@ -126,3 +128,5 @@ } | ||
notifier.opId++ | ||
this._inHook = true | ||
;(hook: any).willMount(target) | ||
this._inHook = false | ||
notifier.trace = oldTrace | ||
@@ -140,3 +144,3 @@ } | ||
const hook = this.cached || this._get() | ||
if (hook.willUnmount) { | ||
if (hook.willUnmount && !this._inWillMount) { | ||
const notifier = this._notifier | ||
@@ -146,3 +150,5 @@ const oldTrace = notifier.trace | ||
notifier.opId++ | ||
this._inHook = true | ||
;(hook: any).willUnmount(target) | ||
this._inHook = false | ||
notifier.trace = oldTrace | ||
@@ -161,3 +167,3 @@ } | ||
} | ||
if (hook.willUpdate) { | ||
if (hook.willUpdate && !this._inHook) { | ||
const notifier = this._notifier | ||
@@ -167,3 +173,5 @@ const oldTrace = notifier.trace | ||
notifier.opId++ | ||
this._inHook = true | ||
;(hook: any).willUpdate(target) | ||
this._inHook = false | ||
notifier.trace = oldTrace | ||
@@ -187,3 +195,5 @@ } | ||
notifier.opId++ | ||
this._inHook = true | ||
;(hook: any).willUnmount(target) | ||
this._inHook = false | ||
notifier.trace = oldTrace | ||
@@ -201,13 +211,9 @@ } | ||
const oldTrace = notifier.trace | ||
notifier.opId++ | ||
if (hook.willUnmount) { | ||
notifier.trace = this.displayName + '.willUnmount' | ||
;(hook: any).willUnmount(target) | ||
this._inHook = true | ||
if (hook.selfUpdate) { | ||
notifier.trace = this.displayName + '.selfUpdate' | ||
;(hook: any).selfUpdate(target) | ||
} | ||
if (hook.willMount) { | ||
notifier.trace = this.displayName + '.willMount' | ||
;(hook: any).willMount(target) | ||
} | ||
notifier.trace = oldTrace | ||
this.context.notifier.flush() | ||
this._inHook = false | ||
} | ||
@@ -214,0 +220,0 @@ |
// @flow | ||
import type {IEntity, ILogger} from '../interfaces' | ||
import type {IEntity} from '../interfaces' | ||
import type {IGetable, ICacheable} from '../utils/resolveArgs' | ||
@@ -11,2 +11,16 @@ import type {IHasDispose, IDisposable} from '../utils/DisposableCollection' | ||
export type ICallerInfo<V> = { | ||
trace: string; | ||
opId: number; | ||
modelName: string; | ||
oldValue: ?V; | ||
newValue: V; | ||
} | ||
export interface ILogger { | ||
onRender(upd: IHasForceUpdate[]): void; | ||
onError(error: Error, name: string): void; | ||
onSetValue<V>(info: ICallerInfo<V>): void; | ||
} | ||
export type IPullable = { | ||
@@ -18,2 +32,3 @@ pull(): ?IHasForceUpdate; | ||
shouldUpdate?: (next: V, prev: V) => boolean; | ||
selfUpdate?: (v: V) => void; | ||
willMount?: (v: V) => void; | ||
@@ -20,0 +35,0 @@ willUnmount?: (v: V) => void; |
// @flow | ||
import type {ILogger} from '../interfaces' | ||
import type {IGetable} from '../utils/resolveArgs' | ||
import type {IHasForceUpdate, INotifierItem} from './interfaces' | ||
import type {ILogger, IHasForceUpdate, INotifierItem} from './interfaces' | ||
import type {IControllable} from '../source/interfaces' | ||
export default class Notifier { | ||
logger: ?IGetable<ILogger> | ||
Updater: Class<IControllable> | ||
@@ -45,15 +46,20 @@ _consumers: INotifierItem[] = [] | ||
} | ||
const consumers = this._consumers | ||
// consumer.pull can recursively run Transact.end, protect from this | ||
this._consumers = [] | ||
const upd: IHasForceUpdate[] = [] | ||
for (let i = 0, l = consumers.length; i < l; i++) { | ||
const consumer = consumers[i] | ||
if (!consumer.cached && !consumer.closed) { | ||
const updater: ?IHasForceUpdate = consumer.pull() | ||
if (updater) { | ||
upd.push(updater) | ||
do { | ||
const consumers = this._consumers | ||
// consumer.pull can recursively run Transact.end, protect from this | ||
this._consumers = [] | ||
for (let i = 0, l = consumers.length; i < l; i++) { | ||
const consumer = consumers[i] | ||
if (!consumer.cached && !consumer.closed) { | ||
const updater: ?IHasForceUpdate = consumer.pull() | ||
if (updater) { | ||
// updater.forceUpdate() | ||
upd.push(updater) | ||
} | ||
} | ||
} | ||
} while (this._consumers.length > 0) | ||
if (this.logger) { | ||
this.logger.get().onRender(upd) | ||
} | ||
@@ -60,0 +66,0 @@ |
@@ -29,2 +29,4 @@ // @flow | ||
export type { | ||
ICallerInfo, | ||
ILogger, | ||
IBaseHook, | ||
@@ -36,3 +38,4 @@ IHasForceUpdate | ||
ISetter, | ||
ISettable | ||
ISettable, | ||
ISource | ||
} from './source/interfaces' | ||
@@ -43,4 +46,2 @@ | ||
IRawArg, | ||
ICallerInfo, | ||
ILogger, | ||
ResultOf | ||
@@ -47,0 +48,0 @@ } from './interfaces' |
@@ -17,16 +17,3 @@ // @flow | ||
export type ICallerInfo<V> = { | ||
trace: string; | ||
opId: number; | ||
modelName: string; | ||
oldValue: ?V; | ||
newValue: V; | ||
} | ||
export interface ILogger { | ||
onError(error: Error, name: string): void; | ||
onSetValue<V>(info: ICallerInfo<V>): void; | ||
} | ||
export type ResultOf<F> = _ResultOf<*, F> | ||
type _ResultOf<V, F: (...x: any[]) => V> = V // eslint-disable-line |
@@ -6,20 +6,16 @@ // @flow | ||
import type {IDisposable, IDisposableCollection} from '../utils/DisposableCollection' | ||
import type {INotifierItem} from '../hook/interfaces' | ||
import type {INotifier, INotifierItem} from '../hook/interfaces' | ||
export type SourceStatusOpts<V: Object> = { | ||
export type SourceStatusOpts = { | ||
complete?: boolean; | ||
pending?: boolean; | ||
error?: ?Error; | ||
promise?: ?Promise<V>; | ||
} | ||
export interface ISourceStatus<V: Object> { | ||
export interface ISourceStatus { | ||
complete: boolean; | ||
pending: boolean; | ||
error: ?Error; | ||
promise: Promise<V>; | ||
isEqual(src: ISourceStatus<*>): boolean; | ||
copy(opts: SourceStatusOpts<V>): ISourceStatus<V>; | ||
_resolve: (v: V) => void; | ||
_reject: (e: Error) => void; | ||
isEqual(src: ISourceStatus): boolean; | ||
copy(opts: SourceStatusOpts): ISourceStatus; | ||
} | ||
@@ -35,7 +31,2 @@ | ||
export interface IControllable { | ||
run(): void; | ||
abort(): void; | ||
} | ||
type IUpdaterBase<V> = { | ||
@@ -54,6 +45,24 @@ next?: (v: V) => void; | ||
export interface IPromisable<V> { | ||
resolve(v: V): void; | ||
reject(e: Error): void; | ||
promise: Promise<V>; | ||
} | ||
export interface IControllable { | ||
constructor<V: Object>( | ||
updater: IUpdater<V>, | ||
source: ISource<V>, | ||
status: ISource<ISourceStatus>, | ||
promisable: IPromisable<V>, | ||
notifier: INotifier | ||
): IControllable; | ||
run(): void; | ||
abort(): void; | ||
} | ||
export interface ISource<V: Object> extends IEntity, IGetable<V>, ISettable<V> { | ||
t: 1; | ||
status: ?ISource<ISourceStatus<V>>; | ||
getStatus(): ISource<ISourceStatus<V>>; | ||
status: ?ISource<ISourceStatus>; | ||
getStatus(): ISource<ISourceStatus>; | ||
@@ -64,2 +73,3 @@ computeds: IDisposableCollection<ICacheable<any> & IDisposable>; | ||
eventSetter(): ISetter<V>; | ||
promise(): Promise<V>; | ||
reset(): void; | ||
@@ -70,5 +80,5 @@ merge(v?: {[id: $Keys<V>]: mixed}): void; | ||
export interface IStatus<V: Object> extends IEntity, IGetable<ISourceStatus<V>>, IDisposable { | ||
export interface IStatus<V: Object> extends IEntity, IGetable<ISourceStatus>, IDisposable { | ||
t: 3; | ||
sources: ISource<ISourceStatus<V>>[]; | ||
sources: ISource<ISourceStatus>[]; | ||
} |
@@ -15,4 +15,4 @@ // @flow | ||
import SourceStatus from './SourceStatus' | ||
import type {IUpdater, ISourceStatus, ISetter, ISource} from './interfaces' | ||
import Updater from './Updater' | ||
import type {IPromisable, IUpdater, ISourceStatus, ISetter, ISource, IControllable} from './interfaces' | ||
import Promisable from './Promisable' | ||
@@ -28,3 +28,3 @@ export default class Source<V: Object> { | ||
closed: boolean | ||
status: ?ISource<ISourceStatus<V>> | ||
status: ?ISource<ISourceStatus> | ||
@@ -76,2 +76,3 @@ _hook: ?IHook<V> | ||
this._eventSetter = null | ||
this._promisable = null | ||
} | ||
@@ -106,3 +107,3 @@ | ||
computeds.push(v) | ||
v.sources.push((source: ISource<ISourceStatus<V>>)) | ||
v.sources.push((source: ISource<ISourceStatus>)) | ||
if (source !== this) { | ||
@@ -183,5 +184,5 @@ level = 0 | ||
getStatus(): ISource<ISourceStatus<V>> { | ||
getStatus(): ISource<ISourceStatus> { | ||
if (!this.status) { | ||
const status: ISource<ISourceStatus<V>> = new Source( | ||
const status: ISource<ISourceStatus> = new Source( | ||
null, | ||
@@ -191,3 +192,3 @@ this.context, | ||
this.displayName + 'Status', | ||
(new SourceStatus(): ISourceStatus<V>) | ||
(new SourceStatus(): ISourceStatus) | ||
) | ||
@@ -201,2 +202,15 @@ // status.status = status | ||
_promisable: ?IPromisable<V> | ||
_getPromisable(): IPromisable<V> { | ||
if (!this._promisable) { | ||
this._promisable = new Promisable() | ||
} | ||
return this._promisable | ||
} | ||
promise(): Promise<V> { | ||
return this._getPromisable().promise | ||
} | ||
merge(v?: {[id: $Keys<V>]: mixed}): void { | ||
@@ -211,3 +225,9 @@ if (!this.cached) { | ||
update(updaterPayload: IUpdater<V>): () => void { | ||
const updater = new Updater(updaterPayload, (this: ISource<V>), this.context.notifier) | ||
const updater: IControllable = new this.context.Updater( | ||
updaterPayload, | ||
(this: ISource<V>), | ||
this.getStatus(), | ||
this._getPromisable(), | ||
this.context.notifier | ||
) | ||
updater.run() | ||
@@ -234,3 +254,2 @@ | ||
} | ||
const context = this.context | ||
const computeds = this.computeds.items | ||
@@ -240,5 +259,5 @@ for (let i = 0, l = computeds.length; i < l; i++) { | ||
} | ||
context.notifier.notify(this.consumers.items, this.displayName, this.cached, v) | ||
this.context.notifier.notify(this.consumers.items, this.displayName, this.cached, v) | ||
this.cached = v | ||
} | ||
} |
@@ -5,27 +5,14 @@ // @flow | ||
export default class SourceStatus<V: Object> implements ISourceStatus<V> { | ||
export default class SourceStatus implements ISourceStatus { | ||
complete: boolean | ||
pending: boolean | ||
error: ?Error | ||
promise: Promise<V> | ||
constructor(opts?: ?SourceStatusOpts<V>) { | ||
constructor(opts?: ?SourceStatusOpts) { | ||
this.complete = !opts || !!opts.complete | ||
this.pending = !!opts && !!opts.pending | ||
this.error = opts ? (opts.error || null) : null | ||
this.promise = opts | ||
? opts.promise || this._createPromise() | ||
: this._createPromise() | ||
} | ||
_resolve: (v: V) => void | ||
_reject: (e: Error) => void | ||
_createPromise(): Promise<V> { | ||
return new Promise((resolve: (v: V) => void, reject: (e: Error) => void) => { | ||
this._resolve = resolve | ||
this._reject = reject | ||
}) | ||
} | ||
isEqual(status: ISourceStatus<V>): boolean { | ||
isEqual(status: ISourceStatus): boolean { | ||
return (status.complete && this.complete) | ||
@@ -36,3 +23,3 @@ || (status.pending && this.pending) | ||
copy(opts: SourceStatusOpts<V>): ISourceStatus<V> { | ||
copy(opts: SourceStatusOpts): ISourceStatus { | ||
const newStatus = new SourceStatus(opts) | ||
@@ -39,0 +26,0 @@ return newStatus.isEqual(this) ? this : newStatus |
@@ -15,5 +15,5 @@ // @flow | ||
closed: boolean | ||
cached: ?ISourceStatus<V> | ||
cached: ?ISourceStatus | ||
sources: ISource<ISourceStatus<V>>[] | ||
sources: ISource<ISourceStatus>[] | ||
@@ -23,3 +23,3 @@ context: IContext | ||
_rawStatuses: IRawArg[] | ||
_key: Class<ISourceStatus<V>> | ||
_key: Class<ISourceStatus> | ||
@@ -62,8 +62,8 @@ constructor( | ||
get(): ISourceStatus<V> { | ||
get(): ISourceStatus { | ||
const sources = this.sources | ||
const newStatus: ISourceStatus<V> = new this._key() // eslint-disable-line | ||
const newStatus: ISourceStatus = new this._key() // eslint-disable-line | ||
for (let i = 0, l = sources.length; i < l; i++) { | ||
const st: ISource<ISourceStatus<V>> = sources[i] | ||
const status: ?ISourceStatus<V> = st.cached | ||
const st: ISource<ISourceStatus> = sources[i] | ||
const status: ?ISourceStatus = st.cached | ||
if (!status || status.pending) { | ||
@@ -70,0 +70,0 @@ newStatus.pending = true |
@@ -8,8 +8,10 @@ // @flow | ||
import type { | ||
ISourceStatus, | ||
IUpdater, | ||
IControllable, | ||
ISource | ||
ISource, | ||
IPromisable | ||
} from './interfaces' | ||
const completeObj = {complete: true, pending: false, error: null, promise: null} | ||
const completeObj = {complete: true, pending: false, error: null} | ||
@@ -43,2 +45,3 @@ export class RecoverableError extends Err { | ||
_source: ISource<V> | ||
_status: ISource<ISourceStatus> | ||
_updater: IUpdater<V> | ||
@@ -51,2 +54,3 @@ _notifier: INotifier | ||
_v: V | ||
_promisable: IPromisable<V> | ||
@@ -56,11 +60,15 @@ constructor( | ||
source: ISource<V>, | ||
status: ISource<ISourceStatus>, | ||
promisable: IPromisable<V>, | ||
notifier: INotifier | ||
) { | ||
this._source = source | ||
this._status = status | ||
this._notifier = notifier | ||
this._updater = updater | ||
this._notifier = notifier | ||
this._promisable = promisable | ||
this._isCanceled = false | ||
this._v = (null: any) | ||
this.displayName = source.displayName | ||
this._id = ++notifier.opId | ||
this._id = ++this._notifier.opId | ||
} | ||
@@ -70,3 +78,3 @@ | ||
const updater = this._updater | ||
const status = this._source.getStatus() | ||
const status = this._status | ||
const pending = { | ||
@@ -132,5 +140,3 @@ complete: false, | ||
notifier.onError(error, this._source.displayName) | ||
const status = this._source.getStatus() | ||
const statusValue = status.cached || status.get() | ||
status.merge({error, complete: false, pending: false, promise: null}) | ||
this._status.merge({error, complete: false, pending: false}) | ||
const observer = this._updater | ||
@@ -140,3 +146,3 @@ if (observer && observer.error) { | ||
} | ||
statusValue._reject(error) | ||
this._promisable.reject(error) | ||
notifier.opId = oldId | ||
@@ -157,8 +163,7 @@ notifier.trace = oldTrace | ||
const source = this._source | ||
const status = source.getStatus() | ||
const statusValue = status.cached || status.get() | ||
const status = this._status | ||
status.merge(completeObj) | ||
if (v) { | ||
this._source.merge(v) | ||
source.merge(v) | ||
} | ||
@@ -169,3 +174,3 @@ const observer = this._updater | ||
} | ||
statusValue._resolve(v || this._v) | ||
this._promisable.resolve(v || this._v) | ||
notifier.opId = oldId | ||
@@ -172,0 +177,0 @@ notifier.trace = oldTrace |
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
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
364984
112
5052
650
0
36