Comparing version 1.1.1 to 1.1.2
@@ -5,2 +5,7 @@ # Change Log | ||
<a name="1.1.2"></a> | ||
## [1.1.2](https://github.com/zerkalica/lom_atom/compare/v1.1.1...v1.1.2) (2017-09-13) | ||
<a name="1.1.1"></a> | ||
@@ -7,0 +12,0 @@ ## [1.1.1](https://github.com/zerkalica/lom_atom/compare/v1.1.0...v1.1.1) (2017-09-06) |
@@ -123,7 +123,7 @@ // eslint-disable-line | ||
var Atom = function () { | ||
function Atom(field, host, context, key, normalize, isComponent, ptr) { | ||
function Atom(field, host, context, normalize, key, isComponent) { | ||
this._masters = null; | ||
this._slaves = null; | ||
this.key = key; | ||
this.field = field; | ||
this.key = key; | ||
this.host = host; | ||
@@ -133,8 +133,16 @@ this.isComponent = isComponent || false; | ||
this._context = context; | ||
var value = ptr === undefined ? undefined : key === undefined ? ptr[field] : ptr[key]; | ||
this.status = value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
this.cached = value; | ||
this._ptr = ptr; | ||
this.value = context.create(host, field, key); | ||
this.status = this.value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
} | ||
Atom.prototype.toString = function toString() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
}; | ||
Atom.prototype.toJSON = function toJSON() { | ||
return this.value; | ||
}; | ||
Atom.prototype.destroyed = function destroyed(isDestroyed) { | ||
@@ -155,17 +163,10 @@ if (isDestroyed === undefined) { | ||
if (this.host.destroy !== undefined) { | ||
this.host.destroy(this.value, this.field, this.key); | ||
} | ||
this._context.destroyHost(this); | ||
this.cached = undefined; | ||
var ptr = this._ptr; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = undefined; | ||
} else { | ||
ptr[this.field] = null; | ||
} | ||
} | ||
this.value = undefined; | ||
this.status = ATOM_STATUS_DESTROYED; | ||
this.key = undefined; | ||
} | ||
@@ -201,7 +202,7 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
Atom.prototype.set = function set$$1(v, force) { | ||
var oldValue = this.cached; | ||
var oldValue = this.value; | ||
@@ -220,13 +221,4 @@ var normalized = this._normalize(v, oldValue); | ||
this.status = ATOM_STATUS_ACTUAL; | ||
this.cached = normalized instanceof Error ? createMock(normalized) : normalized; | ||
var ptr = this._ptr; | ||
this.value = normalized instanceof Error ? createMock(normalized) : normalized; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = this.cached; | ||
} else { | ||
ptr[this.field] = this.cached; | ||
} | ||
} | ||
this._context.newValue(this, oldValue, normalized); | ||
@@ -242,3 +234,3 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
@@ -276,6 +268,6 @@ | ||
context.last = this; | ||
var cached = this.cached; | ||
var value = this.value; | ||
try { | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, cached) : this.host[this.field + '$'](this.key, proposedValue, force, cached), cached); | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, value) : this.host[this.field + '$'](this.key, proposedValue, force, value), value); | ||
} catch (error) { | ||
@@ -293,16 +285,7 @@ if (error[catchedId] === undefined) { | ||
if (newValue !== undefined && cached !== newValue) { | ||
this.cached = newValue; | ||
var ptr = this._ptr; | ||
if (newValue !== undefined && value !== newValue) { | ||
this.value = newValue; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = newValue; | ||
} else { | ||
ptr[this.field] = newValue; | ||
} | ||
} | ||
this._context.newValue(this, value, newValue, true); | ||
this._context.newValue(this, cached, newValue, true); | ||
if (this._slaves) { | ||
@@ -360,12 +343,6 @@ this._slaves.forEach(obsoleteSlave); | ||
Atom.prototype.value = function value(next, force) { | ||
return next === undefined ? this.get(force) : this.set(next, force); | ||
}; | ||
createClass(Atom, [{ | ||
key: "displayName", | ||
get: function get$$1() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
return this.toString(); | ||
} | ||
@@ -390,34 +367,2 @@ }]); | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var value = params[key]; | ||
result += "." + key + ":" + (_typeof(value) === 'object' ? JSON.stringify(value) : value); | ||
} | ||
return result; | ||
} | ||
var lastId = 0; | ||
function getKey(params) { | ||
if (typeof params === 'string' || typeof params === 'number') { | ||
return params; | ||
} | ||
if (!params) { | ||
return 0; | ||
} | ||
if (typeof params === 'function') { | ||
params.__id = params.__id || ++lastId; | ||
return params.__id; | ||
} | ||
return _typeof(params) === 'object' ? getKeyFromObj(params) : JSON.stringify(params); | ||
} | ||
var BaseLogger = function () { | ||
@@ -461,20 +406,5 @@ function BaseLogger() {} | ||
var NoSerializableException = function (_Error) { | ||
inheritsLoose(NoSerializableException, _Error); | ||
function NoSerializableException(host, field) { | ||
var _this2; | ||
_this2 = _Error.call(this, "" + (host.displayName || host.constructor.name) + (field ? "." + field : '') + " not a serializable") || this // $FlowFixMe new.target | ||
; | ||
_this2['__proto__'] = new.target.prototype; | ||
return _this2; | ||
} | ||
return NoSerializableException; | ||
}(Error); | ||
var Context = function () { | ||
function Context() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
@@ -488,6 +418,6 @@ this.last = null; | ||
this.__run = function () { | ||
if (_this3._scheduled) { | ||
_this3._scheduled = false; | ||
if (_this2._scheduled) { | ||
_this2._scheduled = false; | ||
_this3._run(); | ||
_this2._run(); | ||
} | ||
@@ -500,123 +430,8 @@ }; | ||
Context.prototype.hasAtom = function hasAtom(host, key) { | ||
return host[getKey(key) + '@'] !== undefined; // const map = this._atomMap.get(host) | ||
// return map !== undefined && map.has(getKey(key)) | ||
}; | ||
Context.prototype.getAtom = function getAtom(field, host, key, normalize, isComponent) { | ||
// let map = this._atomMap.get(host) | ||
// if (map === undefined) { | ||
// map = new Map() | ||
// this._atomMap.set(host, map) | ||
// } | ||
// let atom: IAtom<V> | void | ||
// let dict = map | ||
// let k | ||
// if (key === undefined) { | ||
// k = field | ||
// atom = map.get(field) | ||
// } else { | ||
// k = getKey(key) | ||
// dict = map.get(field) | ||
// if (dict === undefined) { | ||
// dict = new Map() | ||
// map.set(field, dict) | ||
// } | ||
// atom = dict.get(k) | ||
// } | ||
var k = key === undefined ? field + '@' : field + '.' + getKey(key) + '@'; | ||
var atom = host[k]; | ||
if (atom === undefined) { | ||
var ptr = host.__lom_state; | ||
if (ptr !== undefined) { | ||
if (ptr[field] === undefined) { | ||
ptr = undefined; | ||
} else if (key !== undefined) { | ||
if (ptr[field] === null) { | ||
ptr[field] = {}; | ||
} | ||
ptr = ptr[field]; | ||
if (_typeof(ptr) !== 'object') { | ||
throw new NoSerializableException(host, field); | ||
} | ||
} else if (ptr[field] === null) { | ||
ptr[field] = undefined; | ||
} | ||
} | ||
if (this._logger !== undefined) { | ||
this._logger.create(host, field, key); | ||
} | ||
atom = new Atom(field, host, this, key, normalize, isComponent, ptr) // dict.set(k, atom) | ||
; | ||
host[k] = atom; | ||
Context.prototype.create = function create(host, field, key) { | ||
if (this._logger !== undefined) { | ||
return this._logger.create(host, field, key); | ||
} | ||
return atom; | ||
}; | ||
Context.prototype.getState = function getState(host) { | ||
if (!host.__lom_state) { | ||
throw new NoSerializableException(host); | ||
} | ||
return host.__lom_state; | ||
}; | ||
Context.prototype.setState = function setState(host, state, init) { | ||
if (init) { | ||
host.__lom_state = state; | ||
return; | ||
} | ||
var oldState = host.__lom_state; | ||
if (oldState === undefined) { | ||
throw new NoSerializableException(host); | ||
} | ||
var fields = Object.keys(state); | ||
for (var i = 0; i < fields.length; i++) { | ||
var field = fields[i]; | ||
var value = state[field]; | ||
if (host[field + '?'] !== undefined) { | ||
if (_typeof(value) !== 'object' || value === null) { | ||
throw new NoSerializableException(host, field); | ||
} | ||
var keys = Object.keys(value); | ||
for (var j = 0; j < keys.length; j++) { | ||
var key = keys[j]; | ||
var atom = host[field + '.' + key + '@']; | ||
if (atom !== undefined) { | ||
atom.set(value[key]); | ||
} else { | ||
if (!oldState[field]) { | ||
oldState[field] = {}; | ||
} | ||
oldState[field][key] = value[key]; | ||
} | ||
} | ||
} else { | ||
var _atom = host[field + '@']; | ||
if (_atom !== undefined) { | ||
_atom.set(value); | ||
} else { | ||
oldState[field] = value; | ||
} | ||
} | ||
} | ||
}; | ||
Context.prototype.destroyHost = function destroyHost(atom) { | ||
@@ -626,28 +441,2 @@ if (this._logger !== undefined) { | ||
} | ||
var host = atom.host; | ||
var k = atom.key === undefined ? atom.field + '@' : atom.field + '.' + getKey(atom.key) + '@'; | ||
host[k] = undefined; | ||
if (host._destroyProp !== undefined) { | ||
host._destroyProp(atom.key || atom.field, atom.cached); | ||
} | ||
if (host._destroy !== undefined && atom.key === undefined) { | ||
host._destroy(); | ||
} // const map = this._atomMap.get(host) | ||
// if (map !== undefined) { | ||
// if (host._destroyProp !== undefined) { | ||
// host._destroyProp(atom.key === undefined ? atom.field : atom.key, atom.cached) | ||
// } | ||
// | ||
// map.delete(atom.key === undefined ? atom.field : getKey(atom.key)) | ||
// if (map.size === 0) { | ||
// if (host._destroy !== undefined) { | ||
// host._destroy() | ||
// } | ||
// this._atomMap.delete(host) | ||
// } | ||
// } | ||
}; | ||
@@ -660,13 +449,11 @@ | ||
Context.prototype.newValue = function newValue(atom, from, to, isActualize) { | ||
if (this._logger === undefined) { | ||
return; | ||
if (this._logger !== undefined) { | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
} | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
}; | ||
@@ -757,4 +544,2 @@ | ||
function memMethod(proto, name, descr, normalize, isComponent) { | ||
var handlerKey = name + "$"; | ||
if (descr.value === undefined) { | ||
@@ -764,3 +549,16 @@ throw new TypeError(name + " is not an function (next?: V)"); | ||
proto[handlerKey] = descr.value; | ||
proto[name + "$"] = descr.value; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
var forcedFn = function forcedFn(next, force) { | ||
return this[name](next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -770,3 +568,10 @@ enumerable: descr.enumerable, | ||
value: function value(next, force) { | ||
return defaultContext.getAtom(name, this, undefined, normalize, isComponent).value(next, force); | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, undefined, isComponent); | ||
hostAtoms.set(this, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -776,9 +581,9 @@ }; | ||
function createGetSetHandler(get, set) { | ||
function createGetSetHandler(get$$1, set$$1) { | ||
return function getSetHandler(next) { | ||
if (next === undefined) { | ||
return get.call(this); | ||
return get$$1.call(this); | ||
} | ||
set.call(this, next); | ||
set$$1.call(this, next); | ||
return next; | ||
@@ -803,19 +608,38 @@ }; | ||
proto[name + "#"] = true; | ||
proto[handlerKey] = descr.get === undefined && descr.set === undefined ? createValueHandler(descr.initializer) : createGetSetHandler(descr.get, descr.set); | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(true); | ||
return atom.get(true); | ||
} | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(); | ||
return atom.get(); | ||
}, | ||
set: function set(val) { | ||
set: function set$$1(val) { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val, true); | ||
atom.set(val, true); | ||
return; | ||
@@ -825,3 +649,3 @@ } | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val); | ||
atom.set(val); | ||
} | ||
@@ -831,2 +655,22 @@ }; | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var _value = params[key]; | ||
result += "." + key + ":" + (_typeof(_value) === 'object' ? JSON.stringify(_value) : _value); | ||
} | ||
return result; | ||
} | ||
function getKey(params) { | ||
if (!params) return ''; | ||
if (params instanceof Array) return JSON.stringify(params); | ||
if (_typeof(params) === 'object') return getKeyFromObj(params); | ||
return '' + params; | ||
} | ||
function memKeyMethod(proto, name, descr, normalize) { | ||
@@ -839,9 +683,16 @@ var handler = descr.value; | ||
var handlerKey = name + "$"; | ||
proto[handlerKey] = handler; | ||
proto[name + "$"] = handler; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
proto[handlerKey + '?'] = function (rawKey) { | ||
return defaultContext.hasAtom(this, rawKey); | ||
var forcedFn = function forcedFn(rawKey, next, force) { | ||
return this[name](rawKey, next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -851,3 +702,18 @@ enumerable: descr.enumerable, | ||
value: function value(rawKey, next, force) { | ||
return defaultContext.getAtom(name, this, rawKey, normalize).value(next, force); | ||
var atomMap = hostAtoms.get(this); | ||
if (atomMap === undefined) { | ||
atomMap = new Map(); | ||
hostAtoms.set(this, atomMap); | ||
} | ||
var key = getKey(rawKey); | ||
var atom = atomMap.get(key); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, rawKey); | ||
atomMap.set(key, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -868,5 +734,6 @@ }; | ||
var forceProxyOpts = { | ||
get: function get(t, name) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
get: function get$$1(t, name) { | ||
var forceFn = t[name + "*"]; // is property or get/set magic ? | ||
if (forceFn === undefined) { | ||
isForced = true; | ||
@@ -876,18 +743,7 @@ return t[name]; | ||
var forcedFn = t[name + '$f']; | ||
if (forcedFn === undefined) { | ||
forcedFn = function forcedFn(a, b, c) { | ||
return t[name + '$?'] === undefined ? t[name](a, true) : t[name](a, b, true); | ||
}; | ||
forcedFn.displayName = name + '$f'; | ||
t[name + '$f'] = forcedFn; | ||
} | ||
return forcedFn; | ||
return forceFn.bind(t); | ||
}, | ||
set: function set(t, name, val) { | ||
set: function set$$1(t, name, val) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
if (t[name + "*"] === undefined) { | ||
isForced = true; | ||
@@ -901,12 +757,17 @@ t[name] = val; | ||
}; | ||
function forceGet() { | ||
return new Proxy(this, forceProxyOpts); | ||
} | ||
function force(proto, name, descr) { | ||
var proxyMap = new WeakMap(); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: forceGet | ||
get: function get$$1() { | ||
var proxy = proxyMap.get(this); | ||
if (proxy === undefined) { | ||
proxy = new Proxy(this, forceProxyOpts); | ||
proxyMap.set(this, proxy); | ||
} | ||
return proxy; | ||
} | ||
}; | ||
@@ -1014,3 +875,3 @@ } | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
if (definingProperty) { | ||
@@ -1056,9 +917,2 @@ return this[hk]; | ||
} | ||
function serializable(proto, name, descr) { | ||
if (!proto.__lom_state) { | ||
proto.__lom_state = {}; | ||
} | ||
proto.__lom_state[name] = null; | ||
} | ||
mem.Wait = AtomWait; | ||
@@ -1068,3 +922,3 @@ mem.key = memkey; | ||
export { Atom, mem, serializable, props, memkey, detached, force, action, defaultContext, BaseLogger, ConsoleLogger }; | ||
export { Atom, mem, props, memkey, detached, force, action, defaultContext, BaseLogger, ConsoleLogger }; | ||
//# sourceMappingURL=lom_atom.es.js.map |
@@ -127,7 +127,7 @@ 'use strict'; | ||
var Atom = function () { | ||
function Atom(field, host, context, key, normalize, isComponent, ptr) { | ||
function Atom(field, host, context, normalize, key, isComponent) { | ||
this._masters = null; | ||
this._slaves = null; | ||
this.key = key; | ||
this.field = field; | ||
this.key = key; | ||
this.host = host; | ||
@@ -137,8 +137,16 @@ this.isComponent = isComponent || false; | ||
this._context = context; | ||
var value = ptr === undefined ? undefined : key === undefined ? ptr[field] : ptr[key]; | ||
this.status = value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
this.cached = value; | ||
this._ptr = ptr; | ||
this.value = context.create(host, field, key); | ||
this.status = this.value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
} | ||
Atom.prototype.toString = function toString() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
}; | ||
Atom.prototype.toJSON = function toJSON() { | ||
return this.value; | ||
}; | ||
Atom.prototype.destroyed = function destroyed(isDestroyed) { | ||
@@ -159,17 +167,10 @@ if (isDestroyed === undefined) { | ||
if (this.host.destroy !== undefined) { | ||
this.host.destroy(this.value, this.field, this.key); | ||
} | ||
this._context.destroyHost(this); | ||
this.cached = undefined; | ||
var ptr = this._ptr; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = undefined; | ||
} else { | ||
ptr[this.field] = null; | ||
} | ||
} | ||
this.value = undefined; | ||
this.status = ATOM_STATUS_DESTROYED; | ||
this.key = undefined; | ||
} | ||
@@ -205,7 +206,7 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
Atom.prototype.set = function set$$1(v, force) { | ||
var oldValue = this.cached; | ||
var oldValue = this.value; | ||
@@ -224,13 +225,4 @@ var normalized = this._normalize(v, oldValue); | ||
this.status = ATOM_STATUS_ACTUAL; | ||
this.cached = normalized instanceof Error ? createMock(normalized) : normalized; | ||
var ptr = this._ptr; | ||
this.value = normalized instanceof Error ? createMock(normalized) : normalized; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = this.cached; | ||
} else { | ||
ptr[this.field] = this.cached; | ||
} | ||
} | ||
this._context.newValue(this, oldValue, normalized); | ||
@@ -246,3 +238,3 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
@@ -280,6 +272,6 @@ | ||
context.last = this; | ||
var cached = this.cached; | ||
var value = this.value; | ||
try { | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, cached) : this.host[this.field + '$'](this.key, proposedValue, force, cached), cached); | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, value) : this.host[this.field + '$'](this.key, proposedValue, force, value), value); | ||
} catch (error) { | ||
@@ -297,16 +289,7 @@ if (error[catchedId] === undefined) { | ||
if (newValue !== undefined && cached !== newValue) { | ||
this.cached = newValue; | ||
var ptr = this._ptr; | ||
if (newValue !== undefined && value !== newValue) { | ||
this.value = newValue; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = newValue; | ||
} else { | ||
ptr[this.field] = newValue; | ||
} | ||
} | ||
this._context.newValue(this, value, newValue, true); | ||
this._context.newValue(this, cached, newValue, true); | ||
if (this._slaves) { | ||
@@ -364,12 +347,6 @@ this._slaves.forEach(obsoleteSlave); | ||
Atom.prototype.value = function value(next, force) { | ||
return next === undefined ? this.get(force) : this.set(next, force); | ||
}; | ||
createClass(Atom, [{ | ||
key: "displayName", | ||
get: function get$$1() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
return this.toString(); | ||
} | ||
@@ -394,34 +371,2 @@ }]); | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var value = params[key]; | ||
result += "." + key + ":" + (_typeof(value) === 'object' ? JSON.stringify(value) : value); | ||
} | ||
return result; | ||
} | ||
var lastId = 0; | ||
function getKey(params) { | ||
if (typeof params === 'string' || typeof params === 'number') { | ||
return params; | ||
} | ||
if (!params) { | ||
return 0; | ||
} | ||
if (typeof params === 'function') { | ||
params.__id = params.__id || ++lastId; | ||
return params.__id; | ||
} | ||
return _typeof(params) === 'object' ? getKeyFromObj(params) : JSON.stringify(params); | ||
} | ||
var BaseLogger = function () { | ||
@@ -465,20 +410,5 @@ function BaseLogger() {} | ||
var NoSerializableException = function (_Error) { | ||
inheritsLoose(NoSerializableException, _Error); | ||
function NoSerializableException(host, field) { | ||
var _this2; | ||
_this2 = _Error.call(this, "" + (host.displayName || host.constructor.name) + (field ? "." + field : '') + " not a serializable") || this // $FlowFixMe new.target | ||
; | ||
_this2['__proto__'] = new.target.prototype; | ||
return _this2; | ||
} | ||
return NoSerializableException; | ||
}(Error); | ||
var Context = function () { | ||
function Context() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
@@ -492,6 +422,6 @@ this.last = null; | ||
this.__run = function () { | ||
if (_this3._scheduled) { | ||
_this3._scheduled = false; | ||
if (_this2._scheduled) { | ||
_this2._scheduled = false; | ||
_this3._run(); | ||
_this2._run(); | ||
} | ||
@@ -504,123 +434,8 @@ }; | ||
Context.prototype.hasAtom = function hasAtom(host, key) { | ||
return host[getKey(key) + '@'] !== undefined; // const map = this._atomMap.get(host) | ||
// return map !== undefined && map.has(getKey(key)) | ||
}; | ||
Context.prototype.getAtom = function getAtom(field, host, key, normalize, isComponent) { | ||
// let map = this._atomMap.get(host) | ||
// if (map === undefined) { | ||
// map = new Map() | ||
// this._atomMap.set(host, map) | ||
// } | ||
// let atom: IAtom<V> | void | ||
// let dict = map | ||
// let k | ||
// if (key === undefined) { | ||
// k = field | ||
// atom = map.get(field) | ||
// } else { | ||
// k = getKey(key) | ||
// dict = map.get(field) | ||
// if (dict === undefined) { | ||
// dict = new Map() | ||
// map.set(field, dict) | ||
// } | ||
// atom = dict.get(k) | ||
// } | ||
var k = key === undefined ? field + '@' : field + '.' + getKey(key) + '@'; | ||
var atom = host[k]; | ||
if (atom === undefined) { | ||
var ptr = host.__lom_state; | ||
if (ptr !== undefined) { | ||
if (ptr[field] === undefined) { | ||
ptr = undefined; | ||
} else if (key !== undefined) { | ||
if (ptr[field] === null) { | ||
ptr[field] = {}; | ||
} | ||
ptr = ptr[field]; | ||
if (_typeof(ptr) !== 'object') { | ||
throw new NoSerializableException(host, field); | ||
} | ||
} else if (ptr[field] === null) { | ||
ptr[field] = undefined; | ||
} | ||
} | ||
if (this._logger !== undefined) { | ||
this._logger.create(host, field, key); | ||
} | ||
atom = new Atom(field, host, this, key, normalize, isComponent, ptr) // dict.set(k, atom) | ||
; | ||
host[k] = atom; | ||
Context.prototype.create = function create(host, field, key) { | ||
if (this._logger !== undefined) { | ||
return this._logger.create(host, field, key); | ||
} | ||
return atom; | ||
}; | ||
Context.prototype.getState = function getState(host) { | ||
if (!host.__lom_state) { | ||
throw new NoSerializableException(host); | ||
} | ||
return host.__lom_state; | ||
}; | ||
Context.prototype.setState = function setState(host, state, init) { | ||
if (init) { | ||
host.__lom_state = state; | ||
return; | ||
} | ||
var oldState = host.__lom_state; | ||
if (oldState === undefined) { | ||
throw new NoSerializableException(host); | ||
} | ||
var fields = Object.keys(state); | ||
for (var i = 0; i < fields.length; i++) { | ||
var field = fields[i]; | ||
var value = state[field]; | ||
if (host[field + '?'] !== undefined) { | ||
if (_typeof(value) !== 'object' || value === null) { | ||
throw new NoSerializableException(host, field); | ||
} | ||
var keys = Object.keys(value); | ||
for (var j = 0; j < keys.length; j++) { | ||
var key = keys[j]; | ||
var atom = host[field + '.' + key + '@']; | ||
if (atom !== undefined) { | ||
atom.set(value[key]); | ||
} else { | ||
if (!oldState[field]) { | ||
oldState[field] = {}; | ||
} | ||
oldState[field][key] = value[key]; | ||
} | ||
} | ||
} else { | ||
var _atom = host[field + '@']; | ||
if (_atom !== undefined) { | ||
_atom.set(value); | ||
} else { | ||
oldState[field] = value; | ||
} | ||
} | ||
} | ||
}; | ||
Context.prototype.destroyHost = function destroyHost(atom) { | ||
@@ -630,28 +445,2 @@ if (this._logger !== undefined) { | ||
} | ||
var host = atom.host; | ||
var k = atom.key === undefined ? atom.field + '@' : atom.field + '.' + getKey(atom.key) + '@'; | ||
host[k] = undefined; | ||
if (host._destroyProp !== undefined) { | ||
host._destroyProp(atom.key || atom.field, atom.cached); | ||
} | ||
if (host._destroy !== undefined && atom.key === undefined) { | ||
host._destroy(); | ||
} // const map = this._atomMap.get(host) | ||
// if (map !== undefined) { | ||
// if (host._destroyProp !== undefined) { | ||
// host._destroyProp(atom.key === undefined ? atom.field : atom.key, atom.cached) | ||
// } | ||
// | ||
// map.delete(atom.key === undefined ? atom.field : getKey(atom.key)) | ||
// if (map.size === 0) { | ||
// if (host._destroy !== undefined) { | ||
// host._destroy() | ||
// } | ||
// this._atomMap.delete(host) | ||
// } | ||
// } | ||
}; | ||
@@ -664,13 +453,11 @@ | ||
Context.prototype.newValue = function newValue(atom, from, to, isActualize) { | ||
if (this._logger === undefined) { | ||
return; | ||
if (this._logger !== undefined) { | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
} | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
}; | ||
@@ -761,4 +548,2 @@ | ||
function memMethod(proto, name, descr, normalize, isComponent) { | ||
var handlerKey = name + "$"; | ||
if (descr.value === undefined) { | ||
@@ -768,3 +553,16 @@ throw new TypeError(name + " is not an function (next?: V)"); | ||
proto[handlerKey] = descr.value; | ||
proto[name + "$"] = descr.value; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
var forcedFn = function forcedFn(next, force) { | ||
return this[name](next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -774,3 +572,10 @@ enumerable: descr.enumerable, | ||
value: function value(next, force) { | ||
return defaultContext.getAtom(name, this, undefined, normalize, isComponent).value(next, force); | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, undefined, isComponent); | ||
hostAtoms.set(this, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -780,9 +585,9 @@ }; | ||
function createGetSetHandler(get, set) { | ||
function createGetSetHandler(get$$1, set$$1) { | ||
return function getSetHandler(next) { | ||
if (next === undefined) { | ||
return get.call(this); | ||
return get$$1.call(this); | ||
} | ||
set.call(this, next); | ||
set$$1.call(this, next); | ||
return next; | ||
@@ -807,19 +612,38 @@ }; | ||
proto[name + "#"] = true; | ||
proto[handlerKey] = descr.get === undefined && descr.set === undefined ? createValueHandler(descr.initializer) : createGetSetHandler(descr.get, descr.set); | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(true); | ||
return atom.get(true); | ||
} | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(); | ||
return atom.get(); | ||
}, | ||
set: function set(val) { | ||
set: function set$$1(val) { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val, true); | ||
atom.set(val, true); | ||
return; | ||
@@ -829,3 +653,3 @@ } | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val); | ||
atom.set(val); | ||
} | ||
@@ -835,2 +659,22 @@ }; | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var _value = params[key]; | ||
result += "." + key + ":" + (_typeof(_value) === 'object' ? JSON.stringify(_value) : _value); | ||
} | ||
return result; | ||
} | ||
function getKey(params) { | ||
if (!params) return ''; | ||
if (params instanceof Array) return JSON.stringify(params); | ||
if (_typeof(params) === 'object') return getKeyFromObj(params); | ||
return '' + params; | ||
} | ||
function memKeyMethod(proto, name, descr, normalize) { | ||
@@ -843,9 +687,16 @@ var handler = descr.value; | ||
var handlerKey = name + "$"; | ||
proto[handlerKey] = handler; | ||
proto[name + "$"] = handler; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
proto[handlerKey + '?'] = function (rawKey) { | ||
return defaultContext.hasAtom(this, rawKey); | ||
var forcedFn = function forcedFn(rawKey, next, force) { | ||
return this[name](rawKey, next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -855,3 +706,18 @@ enumerable: descr.enumerable, | ||
value: function value(rawKey, next, force) { | ||
return defaultContext.getAtom(name, this, rawKey, normalize).value(next, force); | ||
var atomMap = hostAtoms.get(this); | ||
if (atomMap === undefined) { | ||
atomMap = new Map(); | ||
hostAtoms.set(this, atomMap); | ||
} | ||
var key = getKey(rawKey); | ||
var atom = atomMap.get(key); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, rawKey); | ||
atomMap.set(key, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -872,5 +738,6 @@ }; | ||
var forceProxyOpts = { | ||
get: function get(t, name) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
get: function get$$1(t, name) { | ||
var forceFn = t[name + "*"]; // is property or get/set magic ? | ||
if (forceFn === undefined) { | ||
isForced = true; | ||
@@ -880,18 +747,7 @@ return t[name]; | ||
var forcedFn = t[name + '$f']; | ||
if (forcedFn === undefined) { | ||
forcedFn = function forcedFn(a, b, c) { | ||
return t[name + '$?'] === undefined ? t[name](a, true) : t[name](a, b, true); | ||
}; | ||
forcedFn.displayName = name + '$f'; | ||
t[name + '$f'] = forcedFn; | ||
} | ||
return forcedFn; | ||
return forceFn.bind(t); | ||
}, | ||
set: function set(t, name, val) { | ||
set: function set$$1(t, name, val) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
if (t[name + "*"] === undefined) { | ||
isForced = true; | ||
@@ -905,12 +761,17 @@ t[name] = val; | ||
}; | ||
function forceGet() { | ||
return new Proxy(this, forceProxyOpts); | ||
} | ||
function force(proto, name, descr) { | ||
var proxyMap = new WeakMap(); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: forceGet | ||
get: function get$$1() { | ||
var proxy = proxyMap.get(this); | ||
if (proxy === undefined) { | ||
proxy = new Proxy(this, forceProxyOpts); | ||
proxyMap.set(this, proxy); | ||
} | ||
return proxy; | ||
} | ||
}; | ||
@@ -1018,3 +879,3 @@ } | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
if (definingProperty) { | ||
@@ -1060,9 +921,2 @@ return this[hk]; | ||
} | ||
function serializable(proto, name, descr) { | ||
if (!proto.__lom_state) { | ||
proto.__lom_state = {}; | ||
} | ||
proto.__lom_state[name] = null; | ||
} | ||
mem.Wait = AtomWait; | ||
@@ -1074,3 +928,2 @@ mem.key = memkey; | ||
exports.mem = mem; | ||
exports.serializable = serializable; | ||
exports.props = props; | ||
@@ -1077,0 +930,0 @@ exports.memkey = memkey; |
@@ -129,7 +129,7 @@ (function (global, factory) { | ||
var Atom = function () { | ||
function Atom(field, host, context, key, normalize, isComponent, ptr) { | ||
function Atom(field, host, context, normalize, key, isComponent) { | ||
this._masters = null; | ||
this._slaves = null; | ||
this.key = key; | ||
this.field = field; | ||
this.key = key; | ||
this.host = host; | ||
@@ -139,8 +139,16 @@ this.isComponent = isComponent || false; | ||
this._context = context; | ||
var value = ptr === undefined ? undefined : key === undefined ? ptr[field] : ptr[key]; | ||
this.status = value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
this.cached = value; | ||
this._ptr = ptr; | ||
this.value = context.create(host, field, key); | ||
this.status = this.value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL; | ||
} | ||
Atom.prototype.toString = function toString() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
}; | ||
Atom.prototype.toJSON = function toJSON() { | ||
return this.value; | ||
}; | ||
Atom.prototype.destroyed = function destroyed(isDestroyed) { | ||
@@ -161,17 +169,10 @@ if (isDestroyed === undefined) { | ||
if (this.host.destroy !== undefined) { | ||
this.host.destroy(this.value, this.field, this.key); | ||
} | ||
this._context.destroyHost(this); | ||
this.cached = undefined; | ||
var ptr = this._ptr; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = undefined; | ||
} else { | ||
ptr[this.field] = null; | ||
} | ||
} | ||
this.value = undefined; | ||
this.status = ATOM_STATUS_DESTROYED; | ||
this.key = undefined; | ||
} | ||
@@ -207,7 +208,7 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
Atom.prototype.set = function set$$1(v, force) { | ||
var oldValue = this.cached; | ||
var oldValue = this.value; | ||
@@ -226,13 +227,4 @@ var normalized = this._normalize(v, oldValue); | ||
this.status = ATOM_STATUS_ACTUAL; | ||
this.cached = normalized instanceof Error ? createMock(normalized) : normalized; | ||
var ptr = this._ptr; | ||
this.value = normalized instanceof Error ? createMock(normalized) : normalized; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = this.cached; | ||
} else { | ||
ptr[this.field] = this.cached; | ||
} | ||
} | ||
this._context.newValue(this, oldValue, normalized); | ||
@@ -248,3 +240,3 @@ | ||
return this.cached; | ||
return this.value; | ||
}; | ||
@@ -282,6 +274,6 @@ | ||
context.last = this; | ||
var cached = this.cached; | ||
var value = this.value; | ||
try { | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, cached) : this.host[this.field + '$'](this.key, proposedValue, force, cached), cached); | ||
newValue = this._normalize(this.key === undefined ? this.host[this.field + '$'](proposedValue, force, value) : this.host[this.field + '$'](this.key, proposedValue, force, value), value); | ||
} catch (error) { | ||
@@ -299,16 +291,7 @@ if (error[catchedId] === undefined) { | ||
if (newValue !== undefined && cached !== newValue) { | ||
this.cached = newValue; | ||
var ptr = this._ptr; | ||
if (newValue !== undefined && value !== newValue) { | ||
this.value = newValue; | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = newValue; | ||
} else { | ||
ptr[this.field] = newValue; | ||
} | ||
} | ||
this._context.newValue(this, value, newValue, true); | ||
this._context.newValue(this, cached, newValue, true); | ||
if (this._slaves) { | ||
@@ -366,12 +349,6 @@ this._slaves.forEach(obsoleteSlave); | ||
Atom.prototype.value = function value(next, force) { | ||
return next === undefined ? this.get(force) : this.set(next, force); | ||
}; | ||
createClass(Atom, [{ | ||
key: "displayName", | ||
get: function get$$1() { | ||
var hc = this.host.constructor; | ||
var k = this.key; | ||
return (this.host.displayName || (hc ? String(hc.displayName || hc.name) : '')) + '.' + this.field + (k ? '(' + (typeof k === 'function' ? k.displayName || k.name : String(k)) + ')' : ''); | ||
return this.toString(); | ||
} | ||
@@ -396,34 +373,2 @@ }]); | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var value = params[key]; | ||
result += "." + key + ":" + (_typeof(value) === 'object' ? JSON.stringify(value) : value); | ||
} | ||
return result; | ||
} | ||
var lastId = 0; | ||
function getKey(params) { | ||
if (typeof params === 'string' || typeof params === 'number') { | ||
return params; | ||
} | ||
if (!params) { | ||
return 0; | ||
} | ||
if (typeof params === 'function') { | ||
params.__id = params.__id || ++lastId; | ||
return params.__id; | ||
} | ||
return _typeof(params) === 'object' ? getKeyFromObj(params) : JSON.stringify(params); | ||
} | ||
var BaseLogger = function () { | ||
@@ -467,20 +412,5 @@ function BaseLogger() {} | ||
var NoSerializableException = function (_Error) { | ||
inheritsLoose(NoSerializableException, _Error); | ||
function NoSerializableException(host, field) { | ||
var _this2; | ||
_this2 = _Error.call(this, "" + (host.displayName || host.constructor.name) + (field ? "." + field : '') + " not a serializable") || this // $FlowFixMe new.target | ||
; | ||
_this2['__proto__'] = new.target.prototype; | ||
return _this2; | ||
} | ||
return NoSerializableException; | ||
}(Error); | ||
var Context = function () { | ||
function Context() { | ||
var _this3 = this; | ||
var _this2 = this; | ||
@@ -494,6 +424,6 @@ this.last = null; | ||
this.__run = function () { | ||
if (_this3._scheduled) { | ||
_this3._scheduled = false; | ||
if (_this2._scheduled) { | ||
_this2._scheduled = false; | ||
_this3._run(); | ||
_this2._run(); | ||
} | ||
@@ -506,123 +436,8 @@ }; | ||
Context.prototype.hasAtom = function hasAtom(host, key) { | ||
return host[getKey(key) + '@'] !== undefined; // const map = this._atomMap.get(host) | ||
// return map !== undefined && map.has(getKey(key)) | ||
}; | ||
Context.prototype.getAtom = function getAtom(field, host, key, normalize, isComponent) { | ||
// let map = this._atomMap.get(host) | ||
// if (map === undefined) { | ||
// map = new Map() | ||
// this._atomMap.set(host, map) | ||
// } | ||
// let atom: IAtom<V> | void | ||
// let dict = map | ||
// let k | ||
// if (key === undefined) { | ||
// k = field | ||
// atom = map.get(field) | ||
// } else { | ||
// k = getKey(key) | ||
// dict = map.get(field) | ||
// if (dict === undefined) { | ||
// dict = new Map() | ||
// map.set(field, dict) | ||
// } | ||
// atom = dict.get(k) | ||
// } | ||
var k = key === undefined ? field + '@' : field + '.' + getKey(key) + '@'; | ||
var atom = host[k]; | ||
if (atom === undefined) { | ||
var ptr = host.__lom_state; | ||
if (ptr !== undefined) { | ||
if (ptr[field] === undefined) { | ||
ptr = undefined; | ||
} else if (key !== undefined) { | ||
if (ptr[field] === null) { | ||
ptr[field] = {}; | ||
} | ||
ptr = ptr[field]; | ||
if (_typeof(ptr) !== 'object') { | ||
throw new NoSerializableException(host, field); | ||
} | ||
} else if (ptr[field] === null) { | ||
ptr[field] = undefined; | ||
} | ||
} | ||
if (this._logger !== undefined) { | ||
this._logger.create(host, field, key); | ||
} | ||
atom = new Atom(field, host, this, key, normalize, isComponent, ptr) // dict.set(k, atom) | ||
; | ||
host[k] = atom; | ||
Context.prototype.create = function create(host, field, key) { | ||
if (this._logger !== undefined) { | ||
return this._logger.create(host, field, key); | ||
} | ||
return atom; | ||
}; | ||
Context.prototype.getState = function getState(host) { | ||
if (!host.__lom_state) { | ||
throw new NoSerializableException(host); | ||
} | ||
return host.__lom_state; | ||
}; | ||
Context.prototype.setState = function setState(host, state, init) { | ||
if (init) { | ||
host.__lom_state = state; | ||
return; | ||
} | ||
var oldState = host.__lom_state; | ||
if (oldState === undefined) { | ||
throw new NoSerializableException(host); | ||
} | ||
var fields = Object.keys(state); | ||
for (var i = 0; i < fields.length; i++) { | ||
var field = fields[i]; | ||
var value = state[field]; | ||
if (host[field + '?'] !== undefined) { | ||
if (_typeof(value) !== 'object' || value === null) { | ||
throw new NoSerializableException(host, field); | ||
} | ||
var keys = Object.keys(value); | ||
for (var j = 0; j < keys.length; j++) { | ||
var key = keys[j]; | ||
var atom = host[field + '.' + key + '@']; | ||
if (atom !== undefined) { | ||
atom.set(value[key]); | ||
} else { | ||
if (!oldState[field]) { | ||
oldState[field] = {}; | ||
} | ||
oldState[field][key] = value[key]; | ||
} | ||
} | ||
} else { | ||
var _atom = host[field + '@']; | ||
if (_atom !== undefined) { | ||
_atom.set(value); | ||
} else { | ||
oldState[field] = value; | ||
} | ||
} | ||
} | ||
}; | ||
Context.prototype.destroyHost = function destroyHost(atom) { | ||
@@ -632,28 +447,2 @@ if (this._logger !== undefined) { | ||
} | ||
var host = atom.host; | ||
var k = atom.key === undefined ? atom.field + '@' : atom.field + '.' + getKey(atom.key) + '@'; | ||
host[k] = undefined; | ||
if (host._destroyProp !== undefined) { | ||
host._destroyProp(atom.key || atom.field, atom.cached); | ||
} | ||
if (host._destroy !== undefined && atom.key === undefined) { | ||
host._destroy(); | ||
} // const map = this._atomMap.get(host) | ||
// if (map !== undefined) { | ||
// if (host._destroyProp !== undefined) { | ||
// host._destroyProp(atom.key === undefined ? atom.field : atom.key, atom.cached) | ||
// } | ||
// | ||
// map.delete(atom.key === undefined ? atom.field : getKey(atom.key)) | ||
// if (map.size === 0) { | ||
// if (host._destroy !== undefined) { | ||
// host._destroy() | ||
// } | ||
// this._atomMap.delete(host) | ||
// } | ||
// } | ||
}; | ||
@@ -666,13 +455,11 @@ | ||
Context.prototype.newValue = function newValue(atom, from, to, isActualize) { | ||
if (this._logger === undefined) { | ||
return; | ||
if (this._logger !== undefined) { | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
} | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom); | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to); | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize); | ||
} | ||
}; | ||
@@ -763,4 +550,2 @@ | ||
function memMethod(proto, name, descr, normalize, isComponent) { | ||
var handlerKey = name + "$"; | ||
if (descr.value === undefined) { | ||
@@ -770,3 +555,16 @@ throw new TypeError(name + " is not an function (next?: V)"); | ||
proto[handlerKey] = descr.value; | ||
proto[name + "$"] = descr.value; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
var forcedFn = function forcedFn(next, force) { | ||
return this[name](next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -776,3 +574,10 @@ enumerable: descr.enumerable, | ||
value: function value(next, force) { | ||
return defaultContext.getAtom(name, this, undefined, normalize, isComponent).value(next, force); | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, undefined, isComponent); | ||
hostAtoms.set(this, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -782,9 +587,9 @@ }; | ||
function createGetSetHandler(get, set) { | ||
function createGetSetHandler(get$$1, set$$1) { | ||
return function getSetHandler(next) { | ||
if (next === undefined) { | ||
return get.call(this); | ||
return get$$1.call(this); | ||
} | ||
set.call(this, next); | ||
set$$1.call(this, next); | ||
return next; | ||
@@ -809,19 +614,38 @@ }; | ||
proto[name + "#"] = true; | ||
proto[handlerKey] = descr.get === undefined && descr.set === undefined ? createValueHandler(descr.initializer) : createGetSetHandler(descr.get, descr.set); | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(true); | ||
return atom.get(true); | ||
} | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(); | ||
return atom.get(); | ||
}, | ||
set: function set(val) { | ||
set: function set$$1(val) { | ||
var atom = hostAtoms.get(this); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize); | ||
hostAtoms.set(this, atom); | ||
} | ||
if (isForced) { | ||
isForced = false; | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val, true); | ||
atom.set(val, true); | ||
return; | ||
@@ -831,3 +655,3 @@ } | ||
defaultContext.getAtom(name, this, undefined, normalize).set(val); | ||
atom.set(val); | ||
} | ||
@@ -837,2 +661,22 @@ }; | ||
function getKeyFromObj(params) { | ||
var keys = Object.keys(params).sort(); | ||
var result = ''; | ||
for (var i = 0; i < keys.length; i++) { | ||
var key = keys[i]; | ||
var _value = params[key]; | ||
result += "." + key + ":" + (_typeof(_value) === 'object' ? JSON.stringify(_value) : _value); | ||
} | ||
return result; | ||
} | ||
function getKey(params) { | ||
if (!params) return ''; | ||
if (params instanceof Array) return JSON.stringify(params); | ||
if (_typeof(params) === 'object') return getKeyFromObj(params); | ||
return '' + params; | ||
} | ||
function memKeyMethod(proto, name, descr, normalize) { | ||
@@ -845,9 +689,16 @@ var handler = descr.value; | ||
var handlerKey = name + "$"; | ||
proto[handlerKey] = handler; | ||
proto[name + "$"] = handler; | ||
var hostAtoms = new WeakMap(); | ||
Object.defineProperty(proto, name + "()", { | ||
get: function get$$1() { | ||
return hostAtoms.get(this); | ||
} | ||
}); | ||
proto[handlerKey + '?'] = function (rawKey) { | ||
return defaultContext.hasAtom(this, rawKey); | ||
var forcedFn = function forcedFn(rawKey, next, force) { | ||
return this[name](rawKey, next, force === undefined ? true : force); | ||
}; | ||
forcedFn.displayName = name + "*"; | ||
proto[name + "*"] = forcedFn; | ||
return { | ||
@@ -857,3 +708,18 @@ enumerable: descr.enumerable, | ||
value: function value(rawKey, next, force) { | ||
return defaultContext.getAtom(name, this, rawKey, normalize).value(next, force); | ||
var atomMap = hostAtoms.get(this); | ||
if (atomMap === undefined) { | ||
atomMap = new Map(); | ||
hostAtoms.set(this, atomMap); | ||
} | ||
var key = getKey(rawKey); | ||
var atom = atomMap.get(key); | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, rawKey); | ||
atomMap.set(key, atom); | ||
} | ||
return next === undefined ? atom.get(force) : atom.set(next, force); | ||
} | ||
@@ -874,5 +740,6 @@ }; | ||
var forceProxyOpts = { | ||
get: function get(t, name) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
get: function get$$1(t, name) { | ||
var forceFn = t[name + "*"]; // is property or get/set magic ? | ||
if (forceFn === undefined) { | ||
isForced = true; | ||
@@ -882,18 +749,7 @@ return t[name]; | ||
var forcedFn = t[name + '$f']; | ||
if (forcedFn === undefined) { | ||
forcedFn = function forcedFn(a, b, c) { | ||
return t[name + '$?'] === undefined ? t[name](a, true) : t[name](a, b, true); | ||
}; | ||
forcedFn.displayName = name + '$f'; | ||
t[name + '$f'] = forcedFn; | ||
} | ||
return forcedFn; | ||
return forceFn.bind(t); | ||
}, | ||
set: function set(t, name, val) { | ||
set: function set$$1(t, name, val) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
if (t[name + "*"] === undefined) { | ||
isForced = true; | ||
@@ -907,12 +763,17 @@ t[name] = val; | ||
}; | ||
function forceGet() { | ||
return new Proxy(this, forceProxyOpts); | ||
} | ||
function force(proto, name, descr) { | ||
var proxyMap = new WeakMap(); | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: forceGet | ||
get: function get$$1() { | ||
var proxy = proxyMap.get(this); | ||
if (proxy === undefined) { | ||
proxy = new Proxy(this, forceProxyOpts); | ||
proxyMap.set(this, proxy); | ||
} | ||
return proxy; | ||
} | ||
}; | ||
@@ -1020,3 +881,3 @@ } | ||
configurable: descr.configurable, | ||
get: function get() { | ||
get: function get$$1() { | ||
if (definingProperty) { | ||
@@ -1062,9 +923,2 @@ return this[hk]; | ||
} | ||
function serializable(proto, name, descr) { | ||
if (!proto.__lom_state) { | ||
proto.__lom_state = {}; | ||
} | ||
proto.__lom_state[name] = null; | ||
} | ||
mem.Wait = AtomWait; | ||
@@ -1076,3 +930,2 @@ mem.key = memkey; | ||
exports.mem = mem; | ||
exports.serializable = serializable; | ||
exports.props = props; | ||
@@ -1079,0 +932,0 @@ exports.memkey = memkey; |
{ | ||
"name": "lom_atom", | ||
"version": "1.1.1", | ||
"version": "1.1.2", | ||
"description": "Observable state management", | ||
@@ -5,0 +5,0 @@ "publishConfig": { |
@@ -135,1 +135,31 @@ # lom_atom | ||
``` | ||
## State load/save | ||
```js | ||
class TodosStore { | ||
@serializable @mem todos [] | ||
} | ||
``` | ||
save: | ||
```js | ||
const store = new TodosStore() | ||
store.todos.push({id: '1', title: 'todo one'}) | ||
store.__lom_state.todos[0].id === '1' | ||
``` | ||
load: | ||
```js | ||
const store = new TodosStore() | ||
// setup initial state | ||
store.__lom_state = { | ||
todos: [{id: 1, title: 'todo one'}] | ||
} | ||
store.todos[0] | ||
``` |
@@ -41,5 +41,5 @@ // @flow | ||
field: string | ||
host: IAtomHost | ||
value: V | void | ||
key: mixed | void | ||
host: IAtomHost | ||
cached: V | void | ||
isComponent: boolean | ||
@@ -51,3 +51,2 @@ | ||
_normalize: INormalize<V> | ||
_ptr: Object | void | ||
@@ -58,9 +57,8 @@ constructor( | ||
context: IContext, | ||
normalize?: INormalize<V>, | ||
key?: mixed, | ||
normalize?: INormalize<V>, | ||
isComponent?: boolean, | ||
ptr?: Object | ||
isComponent?: boolean | ||
) { | ||
this.key = key | ||
this.field = field | ||
this.key = key | ||
this.host = host | ||
@@ -70,13 +68,11 @@ this.isComponent = isComponent || false | ||
this._context = context | ||
const value = ptr === undefined | ||
? undefined | ||
: (key === undefined ? ptr[field] : ptr[key]) | ||
this.status = value === undefined | ||
? ATOM_STATUS_OBSOLETE | ||
: ATOM_STATUS_ACTUAL | ||
this.cached = value | ||
this._ptr = ptr | ||
this.value = context.create(host, field, key) | ||
this.status = this.value === undefined ? ATOM_STATUS_OBSOLETE : ATOM_STATUS_ACTUAL | ||
} | ||
get displayName(): string { | ||
return this.toString() | ||
} | ||
toString() { | ||
const hc = this.host.constructor | ||
@@ -94,2 +90,6 @@ const k = this.key | ||
toJSON() { | ||
return this.value | ||
} | ||
destroyed(isDestroyed?: boolean): boolean { | ||
@@ -107,14 +107,8 @@ if (isDestroyed === undefined) { | ||
this._checkSlaves() | ||
if (this.host.destroy !== undefined) { | ||
this.host.destroy(this.value, this.field, this.key) | ||
} | ||
this._context.destroyHost(this) | ||
this.cached = undefined | ||
const ptr = this._ptr | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = undefined | ||
} else { | ||
ptr[this.field] = null | ||
} | ||
} | ||
this.value = undefined | ||
this.status = ATOM_STATUS_DESTROYED | ||
this.key = undefined | ||
} | ||
@@ -146,7 +140,7 @@ | ||
return (this.cached: any) | ||
return (this.value: any) | ||
} | ||
set(v: V | Error, force?: boolean): V { | ||
let oldValue = this.cached | ||
let oldValue = this.value | ||
const normalized: V = this._normalize((v: any), oldValue) | ||
@@ -162,14 +156,6 @@ if (oldValue === normalized) { | ||
this.cached = normalized instanceof Error | ||
this.value = normalized instanceof Error | ||
? createMock(normalized) | ||
: normalized | ||
const ptr = this._ptr | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = this.cached | ||
} else { | ||
ptr[this.field] = this.cached | ||
} | ||
} | ||
this._context.newValue(this, oldValue, normalized) | ||
@@ -184,3 +170,3 @@ if (this._slaves) { | ||
return (this.cached: any) | ||
return (this.value: any) | ||
} | ||
@@ -219,9 +205,9 @@ | ||
context.last = this | ||
const cached = this.cached | ||
const value = this.value | ||
try { | ||
newValue = this._normalize( | ||
this.key === undefined | ||
? (this.host: any)[this.field + '$'](proposedValue, force, cached) | ||
: (this.host: any)[this.field + '$'](this.key, proposedValue, force, cached), | ||
cached | ||
? (this.host: any)[this.field + '$'](proposedValue, force, value) | ||
: (this.host: any)[this.field + '$'](this.key, proposedValue, force, value), | ||
value | ||
) | ||
@@ -240,14 +226,5 @@ } catch (error) { | ||
if (newValue !== undefined && cached !== newValue) { | ||
this.cached = newValue | ||
const ptr = this._ptr | ||
if (ptr !== undefined) { | ||
if (this.key !== undefined) { | ||
ptr[this.key] = newValue | ||
} else { | ||
ptr[this.field] = newValue | ||
} | ||
} | ||
this._context.newValue(this, cached, newValue, true) | ||
if (newValue !== undefined && value !== newValue) { | ||
this.value = newValue | ||
this._context.newValue(this, value, newValue, true) | ||
if (this._slaves) { | ||
@@ -299,8 +276,2 @@ this._slaves.forEach(obsoleteSlave) | ||
} | ||
value(next?: V | Error, force?: boolean): V { | ||
return next === undefined | ||
? this.get(force) | ||
: this.set(next, force) | ||
} | ||
} |
@@ -5,3 +5,2 @@ // @flow | ||
INormalize, | ||
IAtomHost, | ||
IAtomHandler, | ||
@@ -28,36 +27,4 @@ IAtomInt, | ||
function getKeyFromObj(params: Object): string { | ||
const keys = Object.keys(params) | ||
.sort() | ||
let result = '' | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
const value = params[key] | ||
result += `.${key}:${typeof value === 'object' ? JSON.stringify(value) : value}` | ||
} | ||
return result | ||
} | ||
let lastId = 0 | ||
function getKey(params: any): string | number { | ||
if (typeof params === 'string' || typeof params === 'number') { | ||
return params | ||
} | ||
if (!params) { | ||
return 0 | ||
} | ||
if (typeof params === 'function') { | ||
params.__id = params.__id || ++lastId | ||
return params.__id | ||
} | ||
return typeof params === 'object' | ||
? getKeyFromObj(params) | ||
: JSON.stringify(params) | ||
} | ||
export class BaseLogger implements ILogger { | ||
create<V>(host: IAtomHost, field: string, key?: mixed): V | void {} | ||
create<V>(host: Object, field: string, key?: mixed): V | void {} | ||
destroy(atom: IAtom<*>): void {} | ||
@@ -83,10 +50,2 @@ status(status: ILoggerStatus, atom: IAtom<*>): void {} | ||
export class NoSerializableException extends Error { | ||
constructor(host: IAtomHost, field?: string) { | ||
super(`${host.displayName || host.constructor.name}${field ? `.${field}` : ''} not a serializable`) | ||
// $FlowFixMe new.target | ||
;(this: Object)['__proto__'] = new.target.prototype | ||
} | ||
} | ||
export default class Context implements IContext { | ||
@@ -98,122 +57,10 @@ last: ?IAtomInt = null | ||
_reaping: Set<IAtomInt> = new Set() | ||
// _atomMap: WeakMap<IAtomHost, Map<string | number, IAtomInt>> = new WeakMap() | ||
_scheduled = false | ||
hasAtom(host: IAtomHost, key: mixed): boolean { | ||
return host[getKey(key) + '@'] !== undefined | ||
// const map = this._atomMap.get(host) | ||
// return map !== undefined && map.has(getKey(key)) | ||
} | ||
getAtom<V>( | ||
field: string, | ||
host: IAtomHost, | ||
key?: mixed, | ||
normalize?: INormalize<V>, | ||
isComponent?: boolean, | ||
): IAtom<V> { | ||
// let map = this._atomMap.get(host) | ||
// if (map === undefined) { | ||
// map = new Map() | ||
// this._atomMap.set(host, map) | ||
// } | ||
// let atom: IAtom<V> | void | ||
// let dict = map | ||
// let k | ||
// if (key === undefined) { | ||
// k = field | ||
// atom = map.get(field) | ||
// } else { | ||
// k = getKey(key) | ||
// dict = map.get(field) | ||
// if (dict === undefined) { | ||
// dict = new Map() | ||
// map.set(field, dict) | ||
// } | ||
// atom = dict.get(k) | ||
// } | ||
const k = key === undefined | ||
? (field + '@') | ||
: (field + '.' + getKey(key) + '@') | ||
let atom: IAtom<V> | void = host[k] | ||
if (atom === undefined) { | ||
let ptr: Object | void = host.__lom_state | ||
if (ptr !== undefined) { | ||
if (ptr[field] === undefined) { | ||
ptr = undefined | ||
} else if (key !== undefined) { | ||
if (ptr[field] === null) { | ||
ptr[field] = {} | ||
} | ||
ptr = ptr[field] | ||
if (typeof ptr !== 'object') { | ||
throw new NoSerializableException(host, field) | ||
} | ||
} else if (ptr[field] === null) { | ||
ptr[field] = undefined | ||
} | ||
} | ||
if (this._logger !== undefined) { | ||
this._logger.create(host, field, key) | ||
} | ||
atom = new Atom(field, host, this, key, normalize, isComponent, ptr) | ||
// dict.set(k, atom) | ||
;(host: Object)[k] = (atom: any) | ||
create<V>(host: Object, field: string, key?: mixed): V | void { | ||
if (this._logger !== undefined) { | ||
return this._logger.create(host, field, key) | ||
} | ||
return atom | ||
} | ||
getState(host: Object): Object { | ||
if (!host.__lom_state) { | ||
throw new NoSerializableException(host) | ||
} | ||
return host.__lom_state | ||
} | ||
setState(host: Object, state: Object, init?: boolean) { | ||
if (init) { | ||
host.__lom_state = state | ||
return | ||
} | ||
const oldState = host.__lom_state | ||
if (oldState === undefined) { | ||
throw new NoSerializableException(host) | ||
} | ||
const fields = Object.keys(state) | ||
for (let i = 0; i < fields.length; i++) { | ||
const field = fields[i] | ||
const value = state[field] | ||
if (host[field + '?'] !== undefined) { | ||
if (typeof value !== 'object' || value === null) { | ||
throw new NoSerializableException(host, field) | ||
} | ||
const keys = Object.keys(value) | ||
for (let j = 0; j < keys.length; j++) { | ||
const key = keys[j] | ||
const atom: IAtom<*> | void = host[field + '.' + key + '@'] | ||
if (atom !== undefined) { | ||
atom.set(value[key]) | ||
} else { | ||
if (!oldState[field]) { | ||
oldState[field] = {} | ||
} | ||
oldState[field][key] = value[key] | ||
} | ||
} | ||
} else { | ||
const atom: IAtom<*> | void = host[field + '@'] | ||
if (atom !== undefined) { | ||
atom.set(value) | ||
} else { | ||
oldState[field] = value | ||
} | ||
} | ||
} | ||
} | ||
destroyHost(atom: IAtomInt) { | ||
@@ -223,31 +70,2 @@ if (this._logger !== undefined) { | ||
} | ||
const host = atom.host | ||
const k = atom.key === undefined | ||
? (atom.field + '@') | ||
: (atom.field + '.' + getKey(atom.key) + '@') | ||
host[k] = (undefined: any) | ||
if (host._destroyProp !== undefined) { | ||
host._destroyProp(atom.key || atom.field, atom.cached) | ||
} | ||
if (host._destroy !== undefined && atom.key === undefined) { | ||
host._destroy() | ||
} | ||
// const map = this._atomMap.get(host) | ||
// if (map !== undefined) { | ||
// if (host._destroyProp !== undefined) { | ||
// host._destroyProp(atom.key === undefined ? atom.field : atom.key, atom.cached) | ||
// } | ||
// | ||
// map.delete(atom.key === undefined ? atom.field : getKey(atom.key)) | ||
// if (map.size === 0) { | ||
// if (host._destroy !== undefined) { | ||
// host._destroy() | ||
// } | ||
// this._atomMap.delete(host) | ||
// } | ||
// } | ||
} | ||
@@ -260,12 +78,11 @@ | ||
newValue<V>(atom: IAtom<V>, from?: V | Error, to: V | Error, isActualize?: boolean) { | ||
if (this._logger === undefined) { | ||
return | ||
if (this._logger !== undefined) { | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom) | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to) | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize) | ||
} | ||
} | ||
if (to instanceof AtomWait) { | ||
this._logger.status('waiting', atom) | ||
} else if (to instanceof Error) { | ||
this._logger.error(atom, to) | ||
} else { | ||
this._logger.newValue(atom, from, to, isActualize) | ||
} | ||
} | ||
@@ -272,0 +89,0 @@ |
// @flow | ||
export {default as Atom} from './Atom' | ||
export {default as mem, serializable, props, memkey, detached, force, action} from './mem' | ||
export {default as mem, props, memkey, detached, force, action} from './mem' | ||
export {defaultContext, BaseLogger, ConsoleLogger} from './Context' | ||
@@ -6,0 +6,0 @@ |
@@ -10,6 +10,33 @@ // @flow | ||
export interface ILogger { | ||
create<V>(host: IAtomHost, field: string, key?: mixed): V | void; | ||
/** | ||
* Invokes before atom creating | ||
* | ||
* @param host Object Object with atom | ||
* @param field string property name | ||
* @param key mixed | void for dictionary atoms - dictionary key | ||
*/ | ||
create<V>(host: Object, field: string, key?: mixed): V | void; | ||
/** | ||
* After atom destroy | ||
*/ | ||
destroy(atom: IAtom<*>): void; | ||
/** | ||
* Atom status changes | ||
- 'waiting' - atom fetching from server (mem.Wait throwed) | ||
- 'proposeToReap' - atom probably will be destroyed on next tick | ||
- 'proposeToPull' - atom will be actualized on next tick | ||
*/ | ||
status(status: ILoggerStatus, atom: IAtom<*>): void; | ||
/** | ||
* Error while actualizing atom | ||
*/ | ||
error<V>(atom: IAtom<V>, err: Error): void; | ||
/** | ||
* Atom value changed | ||
* @param isActualize bool if true - atom handler invoked, if false - only atom.cache value getted/setted | ||
*/ | ||
newValue<V>(atom: IAtom<V>, from?: V | Error, to: V, isActualize?: boolean): void; | ||
@@ -20,14 +47,3 @@ } | ||
last: ?IAtomInt; | ||
getAtom<V>( | ||
field: string, | ||
host: IAtomHost, | ||
key?: mixed, | ||
normalize?: INormalize<V>, | ||
isComponent?: boolean | ||
): IAtom<V>; | ||
setState(host: Object, state: Object): void; | ||
getState(host: Object): Object; | ||
hasAtom(host: IAtomHost, key: mixed): boolean; | ||
create<V>(host: Object, field: string, key?: mixed): V | void; | ||
destroyHost(atom: IAtomInt): void; | ||
@@ -56,2 +72,3 @@ newValue<V>(t: IAtom<V>, from?: V | Error, to: V | Error, isActualize?: boolean): void; | ||
status: IAtomStatus; | ||
value: V | void; | ||
+field: string; | ||
@@ -61,3 +78,2 @@ +displayName: string; | ||
set(v: V | Error, force?: boolean): V; | ||
value(next?: V | Error, force?: boolean): V; | ||
destroyed(isDestroyed?: boolean): boolean; | ||
@@ -70,3 +86,2 @@ } | ||
host: IAtomHost; | ||
cached: any; | ||
@@ -88,5 +103,3 @@ actualize(): void; | ||
[key: string]: IAtomHandler<*, *>; | ||
_destroyProp?: (key: mixed, value: mixed | void) => void; | ||
_destroy?: () => void; | ||
__lom_state?: Object; | ||
destroy?: (value: mixed, field: string, key?: mixed) => void; | ||
} |
158
src/mem.js
@@ -6,2 +6,3 @@ // @flow | ||
import {AtomWait} from './utils' | ||
import Atom from './Atom' | ||
@@ -25,8 +26,19 @@ type TypedPropertyDescriptor<T> = { | ||
): TypedPropertyDescriptor<*> { | ||
const handlerKey = `${name}$` | ||
if (descr.value === undefined) { | ||
throw new TypeError(`${name} is not an function (next?: V)`) | ||
} | ||
proto[handlerKey] = descr.value | ||
proto[`${name}$`] = descr.value | ||
const hostAtoms: WeakMap<Object, IAtom<V>> = new WeakMap() | ||
Object.defineProperty(proto, `${name}()`, { | ||
get() { | ||
return hostAtoms.get(this) | ||
} | ||
}) | ||
const forcedFn = function (next?: V | Error, force?: boolean) { | ||
return this[name](next, force === undefined ? true : force) | ||
} | ||
forcedFn.displayName = `${name}*` | ||
proto[`${name}*`] = forcedFn | ||
return { | ||
@@ -36,4 +48,11 @@ enumerable: descr.enumerable, | ||
value(next?: V | Error, force?: boolean): V { | ||
return (defaultContext.getAtom(name, this, undefined, normalize, isComponent): IAtom<V>) | ||
.value(next, force) | ||
let atom: IAtom<V> | void = hostAtoms.get(this) | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, undefined, isComponent) | ||
hostAtoms.set(this, atom) | ||
} | ||
return next === undefined | ||
? (atom: IAtom<V>).get(force) | ||
: (atom: IAtom<V>).set(next, force) | ||
} | ||
@@ -76,3 +95,2 @@ } | ||
} | ||
proto[`${name}#`] = true | ||
@@ -83,2 +101,10 @@ proto[handlerKey] = descr.get === undefined && descr.set === undefined | ||
const hostAtoms: WeakMap<Object, IAtom<V>> = new WeakMap() | ||
Object.defineProperty(proto, `${name}()`, { | ||
get() { | ||
return hostAtoms.get(this) | ||
} | ||
}) | ||
return { | ||
@@ -88,15 +114,25 @@ enumerable: descr.enumerable, | ||
get() { | ||
let atom: IAtom<V> | void = hostAtoms.get(this) | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize) | ||
hostAtoms.set(this, atom) | ||
} | ||
if (isForced) { | ||
isForced = false | ||
return defaultContext.getAtom(name, this, undefined, normalize).get(true) | ||
return atom.get(true) | ||
} | ||
return defaultContext.getAtom(name, this, undefined, normalize).get() | ||
return atom.get() | ||
}, | ||
set(val: V | Error) { | ||
let atom: IAtom<V> | void = hostAtoms.get(this) | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize) | ||
hostAtoms.set(this, atom) | ||
} | ||
if (isForced) { | ||
isForced = false | ||
;(defaultContext.getAtom(name, this, undefined, normalize): IAtom<V>).set(val, true) | ||
;(atom: IAtom<V>).set(val, true) | ||
return | ||
} | ||
;(defaultContext.getAtom(name, this, undefined, normalize): IAtom<V>).set(val) | ||
;(atom: IAtom<V>).set(val) | ||
} | ||
@@ -106,2 +142,24 @@ } | ||
function getKeyFromObj(params: Object): string { | ||
const keys = Object.keys(params) | ||
.sort() | ||
let result = '' | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
const value = params[key] | ||
result += `.${key}:${typeof value === 'object' ? JSON.stringify(value) : value}` | ||
} | ||
return result | ||
} | ||
function getKey(params: any): string { | ||
if (!params) return '' | ||
if (params instanceof Array) return JSON.stringify(params) | ||
if (typeof params === 'object') return getKeyFromObj(params) | ||
return '' + params | ||
} | ||
function memKeyMethod<V, K, P: Object>( | ||
@@ -117,9 +175,14 @@ proto: P, | ||
} | ||
const handlerKey = `${name}$` | ||
proto[handlerKey] = handler | ||
proto[handlerKey + '?'] = function(rawKey: K) { | ||
return defaultContext.hasAtom(this, rawKey) | ||
proto[`${name}$`] = handler | ||
const hostAtoms: WeakMap<Object, Map<string, IAtom<V>>> = new WeakMap() | ||
Object.defineProperty(proto, `${name}()`, { | ||
get() { | ||
return hostAtoms.get(this) | ||
} | ||
}) | ||
const forcedFn = function (rawKey: K, next?: V | Error, force?: boolean) { | ||
return this[name](rawKey, next, force === undefined ? true : force) | ||
} | ||
forcedFn.displayName = `${name}*` | ||
proto[`${name}*`] = forcedFn | ||
@@ -130,9 +193,15 @@ return { | ||
value(rawKey: K, next?: V | Error, force?: boolean) { | ||
return (defaultContext.getAtom( | ||
name, | ||
this, | ||
rawKey, | ||
normalize | ||
): IAtom<V>) | ||
.value(next, force) | ||
let atomMap: Map<string, IAtom<V>> | void = hostAtoms.get(this) | ||
if (atomMap === undefined) { | ||
atomMap = new Map() | ||
hostAtoms.set(this, atomMap) | ||
} | ||
const key = getKey(rawKey) | ||
let atom: IAtom<V> | void = atomMap.get(key) | ||
if (atom === undefined) { | ||
atom = new Atom(name, this, defaultContext, normalize, rawKey) | ||
atomMap.set(key, atom) | ||
} | ||
return next === undefined ? (atom: IAtom<V>).get(force) : (atom: IAtom<V>).set(next, force) | ||
} | ||
@@ -174,5 +243,5 @@ } | ||
get(t: Object, name: string) { | ||
const forceFn = t[`${name}*`] | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
if (forceFn === undefined) { | ||
isForced = true | ||
@@ -182,19 +251,7 @@ return t[name] | ||
let forcedFn = t[name + '$f'] | ||
if (forcedFn === undefined) { | ||
forcedFn = function (a, b, c) { | ||
return t[name + '$?'] === undefined | ||
? t[name](a, true) | ||
: t[name](a, b, true) | ||
} | ||
forcedFn.displayName = name + '$f' | ||
t[name + '$f'] = forcedFn | ||
} | ||
return forcedFn | ||
return forceFn.bind(t) | ||
}, | ||
set(t: Object, name: string, val: mixed) { | ||
// is property or get/set magic ? | ||
if (t[name + '#'] !== undefined) { | ||
if (t[`${name}*`] === undefined) { | ||
isForced = true | ||
@@ -209,6 +266,2 @@ t[name] = val | ||
function forceGet() { | ||
return new Proxy(this, forceProxyOpts) | ||
} | ||
export function force<V>( | ||
@@ -219,6 +272,14 @@ proto: mixed, | ||
): TypedPropertyDescriptor<V> { | ||
const proxyMap: WeakMap<V, any> = new WeakMap() | ||
return { | ||
enumerable: descr.enumerable, | ||
configurable: descr.configurable, | ||
get: forceGet | ||
get() { | ||
let proxy: V | void = proxyMap.get(this) | ||
if (proxy === undefined) { | ||
proxy = new Proxy(this, forceProxyOpts) | ||
proxyMap.set(this, proxy) | ||
} | ||
return proxy | ||
} | ||
} | ||
@@ -373,15 +434,4 @@ } | ||
export function serializable( | ||
proto: Object, | ||
name: string, | ||
descr: TypedPropertyDescriptor<*>, | ||
) { | ||
if (!proto.__lom_state) { | ||
proto.__lom_state = {} | ||
} | ||
proto.__lom_state[name] = null | ||
} | ||
mem.Wait = AtomWait | ||
mem.key = memkey | ||
mem.detached = detached |
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
165
251409
3190