Comparing version 0.12.1 to 0.13.0-beta2
@@ -57,6 +57,2 @@ // UMD loader | ||
function util_arrayContains (a, b) { | ||
return a.indexOf(b) >= 0; | ||
} | ||
var nextId = 0; | ||
@@ -87,115 +83,7 @@ function util_nextId () { | ||
// node modes | ||
var gc_NEW = 0, | ||
gc_CHANGED = 1, | ||
gc_UNCHANGED = 2, | ||
gc_ORPHANED = 3, | ||
gc_UNSTABLE = 4, | ||
gc_STABLE = 5, | ||
gc_DISOWNED = 6; | ||
var epoch_globalEpoch = 0; | ||
function gc_mark(node, reactors) { | ||
// make everything unstable | ||
if (node._type === types_REACTION) { | ||
if (node.reacting) { | ||
throw new Error("Cycle detected! Don't do this!"); | ||
} | ||
reactors.push(node); | ||
} else { | ||
for (var i = node._children.length; i--;) { | ||
var child = node._children[i]; | ||
if (child._state !== gc_UNSTABLE) { | ||
child._state = gc_UNSTABLE; | ||
gc_mark(child, reactors); | ||
} | ||
} | ||
} | ||
} | ||
function gc_sweep(node) { | ||
var i; | ||
switch (node._state) { | ||
case gc_CHANGED: | ||
case gc_UNCHANGED: | ||
// changed or unchanged means the node was visited | ||
// during the react phase, which means we keep it in | ||
// the graph for the next go round | ||
for (i = node._children.length; i--;) { | ||
var child = node._children[i]; | ||
gc_sweep(child); | ||
if (child._state !== gc_STABLE) { | ||
node._children.splice(i, 1); | ||
} | ||
} | ||
node._state = gc_STABLE; | ||
break; | ||
case gc_UNSTABLE: | ||
if (node._type === types_REACTION) { | ||
// only happens when reaction created in transaction. see issue #14 | ||
node._state = gc_STABLE; | ||
} else { | ||
// unstable means the node was not visited during | ||
// the react phase, which means we kick it out of the | ||
// graph. | ||
// but first we check if all of its parents were unchanged | ||
// if so, we can avoid recalculating it in future by | ||
// caching its parents' current values. | ||
var stashedParentStates = []; | ||
for (i = node._parents.length; i--;) { | ||
var parent = node._parents[i]; | ||
if (parent._state !== gc_UNCHANGED) { | ||
// nope, its parents either have changed or weren't visited, | ||
// so we have to orphan this node | ||
node._state = gc_ORPHANED; | ||
break; | ||
} | ||
stashedParentStates.push([parent, parent._value]); | ||
} | ||
if (node._state !== gc_ORPHANED) { | ||
node._state = gc_DISOWNED; | ||
node._parents = stashedParentStates; | ||
} | ||
} | ||
break; | ||
case gc_STABLE: | ||
case gc_ORPHANED: | ||
case gc_DISOWNED: | ||
break; | ||
default: | ||
throw new Error("can't sweep state " + node._state); | ||
} | ||
} | ||
function gc_abort_sweep(node) { | ||
// set everything to unstable, kill all derivation caches and disconnect | ||
// the graph | ||
var doChildren = false; | ||
switch (node._type) { | ||
case types_ATOM: | ||
node._state = gc_STABLE; | ||
doChildren = true; | ||
break; | ||
case types_DERIVATION: | ||
case types_LENS: | ||
node._state = gc_NEW; | ||
node._value = util_unique; | ||
doChildren = true; | ||
break; | ||
case types_REACTION: | ||
node._state = gc_STABLE; | ||
doChildren = false; | ||
break; | ||
} | ||
if (doChildren) { | ||
for (var i = node._children.length; i--;) { | ||
gc_abort_sweep(node._children[i]); | ||
} | ||
node._children = []; | ||
} | ||
} | ||
var parentsStack = []; | ||
function parents_capturingParents(f) { | ||
function parents_capturingParentsEpochs(f) { | ||
var i = parentsStack.length; | ||
@@ -211,8 +99,18 @@ parentsStack.push([]); | ||
function parents_maybeCaptureParent(p) { | ||
function parents_captureParent(p) { | ||
if (parentsStack.length > 0) { | ||
util_addToArray(parentsStack[parentsStack.length - 1], p); | ||
var top = parentsStack[parentsStack.length - 1]; | ||
top.push(p, 0); | ||
return top.length-1; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
function parents_captureEpoch(idx, epoch) { | ||
if (parentsStack.length > 0) { | ||
parentsStack[parentsStack.length - 1][idx] = epoch; | ||
} | ||
} | ||
var types_ATOM = "ATOM", | ||
@@ -223,70 +121,78 @@ types_DERIVATION = "DERIVATION", | ||
var RUNNING = 0, | ||
COMPLETED = 1, | ||
ABORTED = 3; | ||
var TransactionAbortion = {}; | ||
function abortTransaction() { | ||
function initiateAbortion() { | ||
throw TransactionAbortion; | ||
} | ||
function transactions_newContext () { | ||
return {currentTxn: null}; | ||
function TransactionContext(parent) { | ||
this.parent = parent; | ||
this.id2txnAtom = {}; | ||
this.globalEpoch = epoch_globalEpoch; | ||
this.modifiedAtoms = []; | ||
} | ||
function transactions_inTransaction (ctx) { | ||
return ctx.currentTxn !== null; | ||
} | ||
var transactions_currentCtx = null; | ||
function transactions_currentTransaction (ctx) { | ||
return ctx.currentTxn; | ||
function transactions_inTransaction () { | ||
return transactions_currentCtx !== null; | ||
} | ||
function begin (ctx, txn) { | ||
txn._parent = ctx.currentTxn; | ||
txn._state = RUNNING; | ||
ctx.currentTxn = txn; | ||
} | ||
function popTransaction (ctx, cb) { | ||
var txn = ctx.currentTxn; | ||
ctx.currentTxn = txn._parent; | ||
if (txn._state !== RUNNING) { | ||
throw new Error("unexpected state: " + txn._state); | ||
function transactions_transact (f) { | ||
beginTransaction(); | ||
try { | ||
f.call(null, initiateAbortion); | ||
} | ||
cb(txn); | ||
catch (e) { | ||
abortTransaction(); | ||
if (e !== TransactionAbortion) { | ||
throw e; | ||
} | ||
return; | ||
} | ||
commitTransaction(); | ||
} | ||
function commit (ctx) { | ||
popTransaction(ctx, function (txn) { | ||
txn._state = COMPLETED; | ||
txn.onCommit && txn.onCommit(); | ||
}); | ||
function beginTransaction() { | ||
transactions_currentCtx = new TransactionContext(transactions_currentCtx); | ||
} | ||
function abort (ctx) { | ||
popTransaction(ctx, function (txn) { | ||
txn._state = ABORTED; | ||
txn.onAbort && txn.onAbort(); | ||
function commitTransaction() { | ||
var ctx = transactions_currentCtx; | ||
transactions_currentCtx = ctx.parent; | ||
var reactorss = []; | ||
ctx.modifiedAtoms.forEach(function (a) { | ||
if (transactions_currentCtx !== null) { | ||
a.set(ctx.id2txnAtom[a._id]._value); | ||
} | ||
else { | ||
a._set(ctx.id2txnAtom[a._id]._value); | ||
reactorss.push(a._reactors); | ||
} | ||
}); | ||
if (transactions_currentCtx === null) { | ||
epoch_globalEpoch = ctx.globalEpoch; | ||
} else { | ||
transactions_currentCtx.globalEpoch = ctx.globalEpoch; | ||
} | ||
reactorss.forEach(function (reactors) { | ||
reactors.forEach(function (r) { | ||
r._maybeReact(); | ||
}); | ||
}); | ||
} | ||
function transactions_transact (ctx, txn, f) { | ||
begin(ctx, txn); | ||
try { | ||
f(abortTransaction); | ||
} catch (e) { | ||
abort(ctx); | ||
if (e !== TransactionAbortion) { | ||
throw e; | ||
} else { | ||
return; | ||
} | ||
function abortTransaction() { | ||
var ctx = transactions_currentCtx; | ||
transactions_currentCtx = ctx.parent; | ||
if (transactions_currentCtx === null) { | ||
epoch_globalEpoch = ctx.globalEpoch + 1; | ||
} | ||
commit(ctx); | ||
else { | ||
transactions_currentCtx.globalEpoch = ctx.globalEpoch + 1; | ||
} | ||
} | ||
function transactions_ticker (ctx, txnConstructor) { | ||
begin(ctx, txnConstructor()); | ||
function transactions_ticker () { | ||
beginTransaction(); | ||
var disposed = false; | ||
@@ -296,8 +202,14 @@ return { | ||
if (disposed) throw new Error("can't tick disposed ticker"); | ||
commit(ctx); | ||
begin(ctx, txnConstructor()); | ||
commitTransaction(); | ||
beginTransaction(); | ||
}, | ||
stop: function () { | ||
if (disposed) throw new Error("ticker already disposed"); | ||
commit(ctx); | ||
disposed = true; | ||
commitTransaction(); | ||
}, | ||
resetState: function () { | ||
if (disposed) throw new Error("ticker already disposed"); | ||
abortTransaction(); | ||
beginTransaction(); | ||
} | ||
@@ -307,175 +219,139 @@ } | ||
function reactorBase (parent, control) { | ||
var base = { | ||
control: control, // the actual object the user gets | ||
parent: parent, // the parent derivable | ||
parentReactor: null, | ||
dependentReactors: [], | ||
_state: gc_STABLE, | ||
active: false, // whether or not listening for changes in parent | ||
_type: types_REACTION, | ||
uid: util_nextId(), | ||
reacting: false, // whether or not reaction function being invoked | ||
yielding: false, // whether or not letting parentReactor react first | ||
}; | ||
var reactorParentStack = []; | ||
function Reactor(react, derivable) { | ||
this._derivable = derivable; | ||
if (react) { | ||
this.react = react; | ||
} | ||
this._atoms = []; | ||
this._parent = null; | ||
this._active = false; | ||
this._yielding = false; | ||
this._reacting = false; | ||
this._type = types_REACTION; | ||
if (util_DEBUG_MODE) { | ||
base.stack = Error().stack; | ||
this.stack = Error().stack; | ||
} | ||
return base; | ||
} | ||
var cycleMsg = "Cyclical Reactor Dependency! Not allowed!"; | ||
function stop (base) { | ||
if (base.active) { | ||
util_removeFromArray(base.parent._children, base); | ||
if (base.parentReactor) { | ||
orphan(base); | ||
var reactors_Reactor = Reactor; | ||
function captureAtoms(derivable, atoms) { | ||
if (derivable._type === types_ATOM) { | ||
util_addToArray(atoms, derivable); | ||
} | ||
else { | ||
for (var i = 0, len = derivable._lastParentsEpochs.length; i < len; i += 2) { | ||
captureAtoms(derivable._lastParentsEpochs[i], atoms); | ||
} | ||
base.active = false; | ||
base.control.onStop && base.control.onStop(); | ||
} | ||
} | ||
var parentReactorStack = []; | ||
Object.assign(reactors_Reactor.prototype, { | ||
start: function () { | ||
this._lastValue = this._derivable.get(); | ||
this._lastEpoch = this._derivable._epoch; | ||
this._atoms = []; | ||
captureAtoms(this._derivable, this._atoms); | ||
var that = this; | ||
this._atoms.forEach(function (atom) { | ||
util_addToArray(atom._reactors, that); | ||
}); | ||
function start (base) { | ||
if (!base.active) { | ||
util_addToArray(base.parent._children, base); | ||
base.active = true; | ||
base.parent._get(); | ||
// capture reactor dependency relationships | ||
var len = parentReactorStack.length; | ||
var len = reactorParentStack.length; | ||
if (len > 0) { | ||
base.parentReactor = parentReactorStack[len - 1]; | ||
this._parent = reactorParentStack[len - 1]; | ||
} | ||
this._active = true; | ||
this.onStart && this.onStart(); | ||
return this; | ||
}, | ||
_force: function (nextValue) { | ||
try { | ||
reactorParentStack.push(this); | ||
this._reacting = true; | ||
this.react(nextValue); | ||
var oldAtoms = this._atoms; | ||
var newAtoms = []; | ||
this._atoms = newAtoms; | ||
captureAtoms(this._derivable, newAtoms); | ||
base.control.onStart && base.control.onStart(); | ||
} | ||
} | ||
var that = this; | ||
function orphan (base) { | ||
if (base.parentReactor) { | ||
base.parentReactor = null; | ||
} | ||
} | ||
newAtoms.forEach(function (atom) { | ||
var idx = oldAtoms.indexOf(atom); | ||
if (idx === -1) { | ||
util_addToArray(atom._reactors, that); | ||
} else { | ||
oldAtoms[idx] = null; | ||
} | ||
}); | ||
function adopt (parentBase, childBase) { | ||
childBase.parentReactor = parentBase; | ||
} | ||
oldAtoms.forEach(function (atom) { | ||
if (atom !== null) { | ||
util_removeFromArray(atom._reactors, that); | ||
} | ||
}); | ||
function reactors_maybeReact (base) { | ||
if (base.yielding) { | ||
throw Error(cycleMsg); | ||
} | ||
if (base.active && base._state === gc_UNSTABLE) { | ||
if (base.parentReactor !== null) { | ||
try { | ||
base.yielding = true; | ||
reactors_maybeReact(base.parentReactor); | ||
} finally { | ||
base.yielding = false; | ||
} catch (e) { | ||
if (util_DEBUG_MODE) { | ||
console.error(this.stack); | ||
} | ||
throw e; | ||
} finally { | ||
this._reacting = false; | ||
reactorParentStack.pop(); | ||
} | ||
// parent might have deactivated this one | ||
if (base.active) { | ||
var parent = base.parent, parentState = parent._state; | ||
if (parentState === gc_UNSTABLE || | ||
parentState === gc_ORPHANED || | ||
parentState === gc_DISOWNED || | ||
parentState === gc_NEW) { | ||
parent._get(); | ||
} | ||
parentState = parent._state; | ||
}, | ||
force: function () { | ||
this._force(this._derivable.get()); | ||
if (parentState === gc_UNCHANGED) { | ||
base._state = gc_STABLE; | ||
} else if (parentState === gc_CHANGED) { | ||
force(base); | ||
} else { | ||
throw new Error("invalid parent state: " + parentState); | ||
return this; | ||
}, | ||
_maybeReact: function () { | ||
if (this._reacting) { | ||
throw Error('cyclical update detected!!'); | ||
} else if (this._active) { | ||
if (this._yielding) { | ||
throw Error('reactor dependency cycle detected'); | ||
} | ||
} | ||
} | ||
} | ||
function force (base) { | ||
// base.reacting check now in gc_mark; total solution there as opposed to here | ||
if (base.control.react) { | ||
base._state = gc_STABLE; | ||
try { | ||
base.reacting = true; | ||
parentReactorStack.push(base); | ||
if (!util_DEBUG_MODE) { | ||
base.control.react(base.parent._get()); | ||
} else { | ||
try { | ||
base.control.react(base.parent._get()); | ||
} catch (e) { | ||
console.error(base.stack); | ||
throw e; | ||
} | ||
if (this._parent !== null) { | ||
this._yielding = true; | ||
this._parent._maybeReact(); | ||
this._yielding = false; | ||
} | ||
} finally { | ||
parentReactorStack.pop(); | ||
base.reacting = false; | ||
var nextValue = this._derivable.get(); | ||
if (this._derivable._epoch !== this._lastEpoch && | ||
!this._derivable.__equals(nextValue, this._lastValue)) { | ||
this._force(nextValue); | ||
} | ||
this._lastEpoch = this._derivable._epoch; | ||
this._lastValue = nextValue; | ||
} | ||
} else { | ||
throw new Error("No reactor function available."); | ||
} | ||
} | ||
function reactors_Reactor () { | ||
/*jshint validthis:true */ | ||
this._type = types_REACTION; | ||
} | ||
function reactors_createBase (control, parent) { | ||
if (control._base) { | ||
throw new Error("This reactor has already been initialized"); | ||
} | ||
control._base = reactorBase(parent, control); | ||
return control; | ||
} | ||
util_extend(reactors_Reactor.prototype, { | ||
start: function () { | ||
start(this._base); | ||
return this; | ||
}, | ||
stop: function () { | ||
stop(this._base); | ||
var _this = this; | ||
this._atoms.forEach(function (atom) { | ||
return util_removeFromArray(atom._reactors, _this); | ||
}); | ||
this._atoms = []; | ||
this._parent = null; | ||
this._active = false; | ||
this.onStop && this.onStop(); | ||
return this; | ||
}, | ||
force: function () { | ||
force(this._base); | ||
return this; | ||
}, | ||
isActive: function () { | ||
return this._base.active; | ||
}, | ||
orphan: function () { | ||
orphan(this._base); | ||
this._parent = null; | ||
return this; | ||
}, | ||
adopt: function (child) { | ||
if (child._type !== types_REACTION) { | ||
throw Error("reactors can only adopt reactors"); | ||
} | ||
adopt(this._base, child._base); | ||
child._parent = this; | ||
return this; | ||
} | ||
}, | ||
isActive: function () { | ||
return this._active; | ||
}, | ||
}); | ||
function reactors_StandardReactor (f) { | ||
/*jshint validthis:true */ | ||
this._type = types_REACTION; | ||
this.react = f; | ||
} | ||
util_extend(reactors_StandardReactor.prototype, reactors_Reactor.prototype); | ||
function reactors_anonymousReactor (descriptor) { | ||
return util_extend(new reactors_Reactor(), descriptor); | ||
} | ||
function derivable_createPrototype (D, opts) { | ||
@@ -571,7 +447,11 @@ var x = { | ||
if (typeof f === 'function') { | ||
return reactors_createBase(new reactors_StandardReactor(f), this); | ||
return new reactors_Reactor(f, this); | ||
} else if (f instanceof reactors_Reactor) { | ||
return reactors_createBase(f, this); | ||
if (typeof f.react !== 'function') { | ||
throw new Error('reactor missing .react method'); | ||
} | ||
f._derivable = this; | ||
return f; | ||
} else if (f && f.react) { | ||
return reactors_createBase(reactors_anonymousReactor(f), this); | ||
return Object.assign(new reactors_Reactor(null, this), f); | ||
} else { | ||
@@ -656,9 +536,4 @@ throw new Error("Unrecognized type for reactor " + f); | ||
get: function () { | ||
parents_maybeCaptureParent(this); | ||
return this._get(); // abstract protected method, in Java parlance | ||
}, | ||
is: function (other) { | ||
return D.lift(opts.equals)(this, other); | ||
return D.lift(this._equals || opts.equals)(this, other); | ||
}, | ||
@@ -718,2 +593,6 @@ | ||
}, | ||
__equals: function (a, b) { | ||
return (this._equals || opts.equals)(a, b); | ||
}, | ||
}; | ||
@@ -745,99 +624,70 @@ | ||
_forceGet: function () { | ||
var that = this, | ||
i; | ||
var newParents = parents_capturingParents(function () { | ||
var newState; | ||
_forceEval: function () { | ||
var that = this; | ||
var newVal = null; | ||
var parents = parents_capturingParentsEpochs(function () { | ||
if (!util_DEBUG_MODE) { | ||
newState = that._deriver(); | ||
newVal = that._deriver(); | ||
} else { | ||
try { | ||
newState = that._deriver(); | ||
newVal = that._deriver(); | ||
} catch (e) { | ||
console.error(that._stack); | ||
console.error(that.stack); | ||
throw e; | ||
} | ||
} | ||
var equals = that._equals || opts.equals; | ||
that._state = equals(newState, that._value) ? gc_UNCHANGED : gc_CHANGED; | ||
that._value = newState; | ||
}); | ||
// organise parents | ||
for (i = this._parents.length; i--;) { | ||
var possiblyFormerParent = this._parents[i]; | ||
if (!util_arrayContains(newParents, possiblyFormerParent)) { | ||
util_removeFromArray(possiblyFormerParent._children, this); | ||
} | ||
if (!this.__equals(newVal, this._value)) { | ||
this._epoch++; | ||
} | ||
this._parents = newParents; | ||
// add this as child to new parents | ||
for (i = newParents.length; i--;) { | ||
util_addToArray(newParents[i]._children, this); | ||
} | ||
this._lastParentsEpochs = parents; | ||
this._value = newVal; | ||
}, | ||
_get: function () { | ||
var i, parent; | ||
outer: switch (this._state) { | ||
case gc_NEW: | ||
case gc_ORPHANED: | ||
this._forceGet(); | ||
break; | ||
case gc_UNSTABLE: | ||
for (i = 0; i < this._parents.length; i++) { | ||
parent = this._parents[i]; | ||
var parentState = parent._state; | ||
if (parentState === gc_UNSTABLE || | ||
parentState === gc_ORPHANED || | ||
parentState === gc_DISOWNED) { | ||
parent._get(); | ||
_update: function () { | ||
var globalEpoch = transactions_currentCtx === null ? | ||
epoch_globalEpoch : | ||
transactions_currentCtx.globalEpoch; | ||
if (this._lastGlobalEpoch !== globalEpoch) { | ||
if (this._value === util_unique) { | ||
// brand spanking new, so force eval | ||
this._forceEval(); | ||
} else { | ||
for (var i = 0, len = this._lastParentsEpochs.length; i < len; i += 2) { | ||
var parent_1 = this._lastParentsEpochs[i]; | ||
var lastParentEpoch = this._lastParentsEpochs[i + 1]; | ||
var currentParentEpoch; | ||
if (parent_1._type === types_ATOM) { | ||
currentParentEpoch = parent_1._getEpoch(); | ||
} else { | ||
parent_1._update(); | ||
currentParentEpoch = parent_1._epoch; | ||
} | ||
if (currentParentEpoch !== lastParentEpoch) { | ||
this._forceEval(); | ||
return; | ||
} | ||
} | ||
parentState = parent._state; | ||
if (parentState === gc_CHANGED) { | ||
this._forceGet(); | ||
break outer; | ||
} else if (!(parentState === gc_STABLE || | ||
parentState === gc_UNCHANGED)) { | ||
throw new Error("invalid parent mode: " + parentState); | ||
} | ||
} | ||
this._state = gc_UNCHANGED; | ||
break; | ||
case gc_DISOWNED: | ||
var parents = []; | ||
for (i = 0; i < this._parents.length; i++) { | ||
var parentStateTuple = this._parents[i], | ||
state = parentStateTuple[1]; | ||
parent = parentStateTuple[0]; | ||
if (!opts.equals(parent._get(), state)) { | ||
this._parents = []; | ||
this._forceGet(); | ||
break outer; | ||
} else { | ||
parents.push(parent); | ||
} | ||
} | ||
for (i = parents.length; i--;) { | ||
util_addToArray(parents[i]._children, this); | ||
} | ||
this._parents = parents; | ||
this._state = gc_UNCHANGED; | ||
break; | ||
default: | ||
// noop | ||
this._lastGlobalEpoch = globalEpoch; | ||
} | ||
}, | ||
get: function () { | ||
var idx = parents_captureParent(this); | ||
this._update(); | ||
parents_captureEpoch(idx, this._epoch); | ||
return this._value; | ||
} | ||
} | ||
}, | ||
}; | ||
} | ||
function derivation_construct(obj, deriver) { | ||
obj._children = []; | ||
obj._parents = []; | ||
obj._deriver = deriver; | ||
obj._state = gc_NEW; | ||
obj._lastParentsEpochs = []; | ||
obj._lastGlobalEpoch = epoch_globalEpoch - 1; | ||
obj._epoch = 0; | ||
obj._type = types_DERIVATION; | ||
@@ -848,3 +698,3 @@ obj._value = util_unique; | ||
if (util_DEBUG_MODE) { | ||
obj._stack = Error().stack; | ||
obj.stack = Error().stack; | ||
} | ||
@@ -872,4 +722,4 @@ | ||
}); | ||
} | ||
} | ||
}, | ||
}; | ||
} | ||
@@ -889,4 +739,4 @@ | ||
return this; | ||
} | ||
} | ||
}, | ||
}; | ||
} | ||
@@ -901,73 +751,2 @@ | ||
function processReactorQueue (rq) { | ||
for (var i = rq.length; i--;) { | ||
reactors_maybeReact(rq[i]); | ||
} | ||
} | ||
var TXN_CTX = transactions_newContext(); | ||
function atom_inTxn () { | ||
return transactions_inTransaction(TXN_CTX) | ||
} | ||
var NOOP_ARRAY = {push: function () {}}; | ||
function TransactionState () { | ||
this.inTxnValues = {}; | ||
this.reactorQueue = []; | ||
} | ||
function getState (txnState, atom) { | ||
var inTxnValue = txnState.inTxnValues[atom._uid]; | ||
if (inTxnValue) { | ||
return inTxnValue[1]; | ||
} else { | ||
return atom._value; | ||
} | ||
} | ||
function setState (txnState, atom, state) { | ||
txnState.inTxnValues[atom._uid] = [atom, state]; | ||
gc_mark(atom, txnState.reactorQueue); | ||
} | ||
util_extend(TransactionState.prototype, { | ||
onCommit: function () { | ||
var i, atomValueTuple; | ||
var keys = util_keys(this.inTxnValues); | ||
if (atom_inTxn()) { | ||
// push in-txn vals up to current txn | ||
for (i = keys.length; i--;) { | ||
atomValueTuple = this.inTxnValues[keys[i]]; | ||
atomValueTuple[0].set(atomValueTuple[1]); | ||
} | ||
} else { | ||
// change root state and run reactors. | ||
for (i = keys.length; i--;) { | ||
atomValueTuple = this.inTxnValues[keys[i]]; | ||
atomValueTuple[0]._value = atomValueTuple[1]; | ||
gc_mark(atomValueTuple[0], NOOP_ARRAY); | ||
} | ||
processReactorQueue(this.reactorQueue); | ||
// then sweep for a clean finish | ||
for (i = keys.length; i--;) { | ||
gc_sweep(this.inTxnValues[keys[i]][0]); | ||
} | ||
} | ||
}, | ||
onAbort: function () { | ||
if (!atom_inTxn()) { | ||
var keys = util_keys(this.inTxnValues); | ||
for (var i = keys.length; i--;) { | ||
gc_abort_sweep(this.inTxnValues[keys[i]][0]); | ||
} | ||
} | ||
} | ||
}) | ||
function atom_createPrototype (D, opts) { | ||
@@ -979,58 +758,64 @@ return { | ||
withValidator: function (f) { | ||
if (f === null) { | ||
return this._clone(); | ||
} if (typeof f === 'function') { | ||
var result = this._clone(); | ||
var existing = this._validator; | ||
if (existing) { | ||
result._validator = function (x) { return f(x) && existing(x); } | ||
} else { | ||
result._validator = f; | ||
set: function (value) { | ||
if (transactions_currentCtx !== null) { | ||
var inTxnThis = void 0; | ||
if ((inTxnThis = transactions_currentCtx.id2txnAtom[this._id]) !== void 0 && | ||
value !== inTxnThis._value) { | ||
transactions_currentCtx.globalEpoch++; | ||
inTxnThis._epoch++; | ||
inTxnThis._value = value; | ||
} else if (!this.__equals(value, this._value)) { | ||
transactions_currentCtx.globalEpoch++; | ||
inTxnThis = this._clone(); | ||
inTxnThis._value = value; | ||
inTxnThis._id = this._id; | ||
inTxnThis._epoch = this._epoch + 1; | ||
transactions_currentCtx.id2txnAtom[this._id] = inTxnThis; | ||
util_addToArray(transactions_currentCtx.modifiedAtoms, this); | ||
} | ||
return result; | ||
} else { | ||
throw new Error(".withValidator expects function or null"); | ||
if (!this.__equals(value, this._value)) { | ||
this._set(value); | ||
this._reactors.forEach(function (r) { return r._maybeReact(); }); | ||
} | ||
} | ||
}, | ||
validate: function () { | ||
this._validate(this.get()); | ||
_set: function (value) { | ||
epoch_globalEpoch++; | ||
this._epoch++; | ||
this._value = value; | ||
}, | ||
_validate: function (value) { | ||
var validationResult = this._validator && this._validator(value); | ||
if (this._validator && validationResult !== true) { | ||
throw new Error("Failed validation with value: '" + value + "'." + | ||
" Validator returned '" + validationResult + "' "); | ||
get: function () { | ||
var inTxnThis; | ||
var txnCtx = transactions_currentCtx; | ||
while (txnCtx !== null) { | ||
inTxnThis = txnCtx.id2txnAtom[this._id]; | ||
if (inTxnThis !== void 0) { | ||
parents_captureEpoch(parents_captureParent(this), inTxnThis._epoch); | ||
return inTxnThis._value; | ||
} | ||
else { | ||
txnCtx = txnCtx.parent; | ||
} | ||
} | ||
parents_captureEpoch(parents_captureParent(this), this._epoch); | ||
return this._value; | ||
}, | ||
set: function (value) { | ||
this._validate(value); | ||
var equals = this._equals || opts.equals; | ||
if (!equals(value, this._value)) { | ||
this._state = gc_CHANGED; | ||
if (atom_inTxn()) { | ||
setState(transactions_currentTransaction(TXN_CTX), this, value); | ||
} else { | ||
this._value = value; | ||
var reactorQueue = []; | ||
gc_mark(this, reactorQueue); | ||
processReactorQueue(reactorQueue); | ||
gc_sweep(this); | ||
_getEpoch: function () { | ||
var inTxnThis; | ||
var txnCtx = transactions_currentCtx; | ||
while (txnCtx !== null) { | ||
inTxnThis = txnCtx.id2txnAtom[this._id]; | ||
if (inTxnThis !== void 0) { | ||
return inTxnThis._epoch; | ||
} | ||
else { | ||
txnCtx = txnCtx.parent; | ||
} | ||
} | ||
return this; | ||
return this._epoch; | ||
}, | ||
_get: function () { | ||
if (atom_inTxn()) { | ||
return getState(transactions_currentTransaction(TXN_CTX), this); | ||
} | ||
return this._value; | ||
} | ||
}; | ||
@@ -1040,5 +825,5 @@ } | ||
function atom_construct (atom, value) { | ||
atom._uid = util_nextId(); | ||
atom._children = []; | ||
atom._state = gc_STABLE; | ||
atom._id = util_nextId(); | ||
atom._reactors = []; | ||
atom._epoch = 0; | ||
atom._value = value; | ||
@@ -1050,6 +835,2 @@ atom._type = types_ATOM; | ||
function atom_transact (f) { | ||
transactions_transact(TXN_CTX, new TransactionState(), f); | ||
} | ||
function atom_transaction (f) { | ||
@@ -1060,3 +841,3 @@ return function () { | ||
var result; | ||
atom_transact(function () { | ||
transactions_transact(function () { | ||
result = f.apply(that, args); | ||
@@ -1074,5 +855,3 @@ }); | ||
} else { | ||
ticker = transactions_ticker(TXN_CTX, function () { | ||
return new TransactionState(); | ||
}); | ||
ticker = transactions_ticker(); | ||
ticker.refCount = 1; | ||
@@ -1093,3 +872,3 @@ } | ||
done = true; | ||
} | ||
}, | ||
}; | ||
@@ -1104,3 +883,3 @@ } | ||
var D = { | ||
transact: atom_transact, | ||
transact: transactions_transact, | ||
defaultEquals: util_equals, | ||
@@ -1166,3 +945,3 @@ setDebugMode: util_setDebugMode, | ||
D.atomically = function (f) { | ||
if (atom_inTxn()) { | ||
if (transactions_inTransaction()) { | ||
f(); | ||
@@ -1169,0 +948,0 @@ } else { |
@@ -1,8 +0,7 @@ | ||
!function(t,n){"use strict";t&&"function"==typeof t.define&&t.define.amd?t.define(["exports"],n):n("undefined"!=typeof exports?exports:t.Derivable={})}(this,function(t){"use strict";function n(t){for(var n=1;n<arguments.length;n++)for(var e=arguments[n],r=nt(e),i=r.length;i--;){var a=r[i];t[a]=e[a]}return t}function e(t,n){return t===n?0!==t||1/t===1/n:t!==t&&n!==n}function r(t,n){return e(t,n)||t&&"function"==typeof t.equals&&t.equals(n)}function i(t,n){var e=t.indexOf(n);0>e&&t.push(n)}function a(t,n){var e=t.indexOf(n);e>=0&&t.splice(e,1)}function u(t,n){return t.indexOf(n)>=0}function o(){return et++}function c(t,n){return Array.prototype.slice.call(t,n)}function s(t){return null!==t&&void 0!==t}function f(t){it=!!t}function l(t,n){return t._equals=n,t}function h(t,n){if(t._type===dt){if(t.reacting)throw new Error("Cycle detected! Don't do this!");n.push(t)}else for(var e=t._children.length;e--;){var r=t._children[e];r._state!==st&&(r._state=st,h(r,n))}}function p(t){var n;switch(t._state){case ut:case ot:for(n=t._children.length;n--;){var e=t._children[n];p(e),e._state!==ft&&t._children.splice(n,1)}t._state=ft;break;case st:if(t._type===dt)t._state=ft;else{var r=[];for(n=t._parents.length;n--;){var i=t._parents[n];if(i._state!==ot){t._state=ct;break}r.push([i,i._value])}t._state!==ct&&(t._state=lt,t._parents=r)}break;case ft:case ct:case lt:break;default:throw new Error("can't sweep state "+t._state)}}function _(t){var n=!1;switch(t._type){case pt:t._state=ft,n=!0;break;case _t:case vt:t._state=at,t._value=rt,n=!0;break;case dt:t._state=ft,n=!1}if(n){for(var e=t._children.length;e--;)_(t._children[e]);t._children=[]}}function v(t){var n=ht.length;ht.push([]);try{return t(),ht[n]}finally{ht.pop()}}function d(t){ht.length>0&&i(ht[ht.length-1],t)}function g(){throw mt}function y(){return{currentTxn:null}}function w(t){return null!==t.currentTxn}function m(t){return t.currentTxn}function k(t,n){n._parent=t.currentTxn,n._state=gt,t.currentTxn=n}function b(t,n){var e=t.currentTxn;if(t.currentTxn=e._parent,e._state!==gt)throw new Error("unexpected state: "+e._state); | ||
n(e)}function E(t){b(t,function(t){t._state=yt,t.onCommit&&t.onCommit()})}function x(t){b(t,function(t){t._state=wt,t.onAbort&&t.onAbort()})}function T(t,n,e){k(t,n);try{e(g)}catch(r){if(x(t),r!==mt)throw r;return}E(t)}function q(t,n){k(t,n());var e=!1;return{tick:function(){if(e)throw new Error("can't tick disposed ticker");E(t),k(t,n())},stop:function(){if(e)throw new Error("ticker already disposed");E(t)}}}function A(t,n){var e={control:n,parent:t,parentReactor:null,dependentReactors:[],_state:ft,active:!1,_type:dt,uid:o(),reacting:!1,yielding:!1};return it&&(e.stack=Error().stack),e}function O(t){t.active&&(a(t.parent._children,t),t.parentReactor&&R(t),t.active=!1,t.control.onStop&&t.control.onStop())}function D(t){if(!t.active){i(t.parent._children,t),t.active=!0,t.parent._get();var n=bt.length;n>0&&(t.parentReactor=bt[n-1]),t.control.onStart&&t.control.onStart()}}function R(t){t.parentReactor&&(t.parentReactor=null)}function V(t,n){n.parentReactor=t}function j(t){if(t.yielding)throw Error(kt);if(t.active&&t._state===st){if(null!==t.parentReactor)try{t.yielding=!0,j(t.parentReactor)}finally{t.yielding=!1}if(t.active){var n=t.parent,e=n._state;if((e===st||e===ct||e===lt||e===at)&&n._get(),e=n._state,e===ot)t._state=ft;else{if(e!==ut)throw new Error("invalid parent state: "+e);C(t)}}}}function C(t){if(!t.control.react)throw new Error("No reactor function available.");t._state=ft;try{if(t.reacting=!0,bt.push(t),it)try{t.control.react(t.parent._get())}catch(n){throw console.error(t.stack),n}else t.control.react(t.parent._get())}finally{bt.pop(),t.reacting=!1}}function S(){this._type=dt}function N(t,n){if(t._base)throw new Error("This reactor has already been initialized");return t._base=A(n,t),t}function F(t){this._type=dt,this.react=t}function G(t){return n(new S,t)}function z(t,n){var e={derive:function(n,e,r,i,a){var u=this;switch(arguments.length){case 0:return u;case 1:switch(typeof n){case"function":return t.derivation(function(){return n(u.get())});case"string":case"number":return t.derivation(function(){return u.get()[t.unpack(n)]; | ||
});default:if(n instanceof Array)return n.map(function(t){return u.derive(t)});if(n instanceof RegExp)return t.derivation(function(){return u.get().match(n)});if(t.isDerivable(n))return t.derivation(function(){var e=n.get(),r=u.get();switch(typeof e){case"function":return e(r);case"string":case"number":return r[e];default:if(e instanceof RegExp)return r.match(e);throw Error("type error")}return u.get()[t.unpack(n)]});throw Error("type error")}break;case 2:return t.derivation(function(){return n(u.get(),t.unpack(e))});case 3:return t.derivation(function(){return n(u.get(),t.unpack(e),t.unpack(r))});case 4:return t.derivation(function(){return n(u.get(),t.unpack(e),t.unpack(r),t.unpack(i))});case 5:return t.derivation(function(){return n(u.get(),t.unpack(e),t.unpack(r),t.unpack(i),t.unpack(a))});default:var o=[u].concat(c(arguments,1));return t.derivation(function(){return n.apply(null,o.map(t.unpack))})}},reactor:function(t){if("function"==typeof t)return N(new F(t),this);if(t instanceof S)return N(t,this);if(t&&t.react)return N(G(t),this);throw new Error("Unrecognized type for reactor "+t)},react:function(n,e){function r(n,e){if(!t.isDerivable(n))if("function"==typeof n)n=t.derivation(n);else{if("boolean"!=typeof n)throw Error("react "+e+" condition must be derivable");n=t.atom(n)}return n.derive(function(t){return!!t})}if("function"!=typeof n)throw Error("the first argument to .react must be a function");e=Object.assign({once:!1,from:!0,until:!1,when:!0,skipFirst:!1},e);var i=this.reactor({react:function(t){e.skipFirst?e.skipFirst=!1:(n(t),e.once&&(this.stop(),a.stop()))},onStart:e.onStart,onStop:e.onStop}),a=t.struct({until:r(e.until,"until"),when:r(e.when,"when")}).reactor(function(t){t.until?(i.stop(),this.stop()):t.when?i.isActive()||i.start().force():i.isActive()&&i.stop()});r(e.from,"from").reactor(function(t){t&&(a.start().force(),this.stop())}).start().force()},get:function(){return d(this),this._get()},is:function(e){return t.lift(n.equals)(this,e)},and:function(n){return this.derive(function(e){return e&&t.unpack(n); | ||
})},or:function(n){return this.derive(function(e){return e||t.unpack(n)})},then:function(n,e){return this.derive(function(r){return t.unpack(r?n:e)})},mThen:function(n,e){return this.derive(function(r){return t.unpack(s(r)?n:e)})},mOr:function(t){return this.mThen(this,t)},mDerive:function(t){if(1===arguments.length&&t instanceof Array){var n=this;return t.map(function(t){return n.mDerive(t)})}return this.mThen(this.derive.apply(this,arguments))},mAnd:function(t){return this.mThen(t,this)},not:function(){return this.derive(function(t){return!t})},withEquality:function(t){if(t){if("function"!=typeof t)throw new Error("equals must be function")}else t=null;return l(this._clone(),t)}};return e["switch"]=function(){var e=arguments;return this.derive(function(r){var i;for(i=0;e.length-1>i;i+=2)if(n.equals(r,t.unpack(e[i])))return t.unpack(e[i+1]);return i===e.length-1?t.unpack(e[i]):void 0})},e}function I(t,n){return{_clone:function(){return l(t.derivation(this._deriver),this._equals)},_forceGet:function(){var t,e=this,r=v(function(){var t;if(it)try{t=e._deriver()}catch(r){throw console.error(e._stack),r}else t=e._deriver();var i=e._equals||n.equals;e._state=i(t,e._value)?ot:ut,e._value=t});for(t=this._parents.length;t--;){var o=this._parents[t];u(r,o)||a(o._children,this)}for(this._parents=r,t=r.length;t--;)i(r[t]._children,this)},_get:function(){var t,e;t:switch(this._state){case at:case ct:this._forceGet();break;case st:for(t=0;this._parents.length>t;t++){e=this._parents[t];var r=e._state;if((r===st||r===ct||r===lt)&&e._get(),r=e._state,r===ut){this._forceGet();break t}if(r!==ft&&r!==ot)throw new Error("invalid parent mode: "+r)}this._state=ot;break;case lt:var a=[];for(t=0;this._parents.length>t;t++){var u=this._parents[t],o=u[1];if(e=u[0],!n.equals(e._get(),o)){this._parents=[],this._forceGet();break t}a.push(e)}for(t=a.length;t--;)i(a[t]._children,this);this._parents=a,this._state=ot}return this._value}}}function Q(t,n){return t._children=[],t._parents=[],t._deriver=n,t._state=at,t._type=_t,t._value=rt,t._equals=null, | ||
it&&(t._stack=Error().stack),t}function L(t,n){return{swap:function(t){var n=c(arguments,0);return n[0]=this.get(),this.set(t.apply(null,n))},lens:function(n){var e=this;return t.lens({get:function(){return n.get(e.get())},set:function(t){e.set(n.set(e.get(),t))}})}}}function M(t,n){return{_clone:function(){return l(t.lens(this._lensDescriptor),this._equals)},set:function(n){var e=this;return t.atomically(function(){e._lensDescriptor.set(n)}),this}}}function U(t,n){return t._lensDescriptor=n,t._type=vt,t}function B(t){for(var n=t.length;n--;)j(t[n])}function H(){return w(Et)}function J(){this.inTxnValues={},this.reactorQueue=[]}function K(t,n){var e=t.inTxnValues[n._uid];return e?e[1]:n._value}function P(t,n,e){t.inTxnValues[n._uid]=[n,e],h(n,t.reactorQueue)}function W(t,n){return{_clone:function(){return l(t.atom(this._value),this._equals)},withValidator:function(t){if(null===t)return this._clone();if("function"==typeof t){var n=this._clone(),e=this._validator;return n._validator=e?function(n){return t(n)&&e(n)}:t,n}throw new Error(".withValidator expects function or null")},validate:function(){this._validate(this.get())},_validate:function(t){var n=this._validator&&this._validator(t);if(this._validator&&n!==!0)throw new Error("Failed validation with value: '"+t+"'. Validator returned '"+n+"' ")},set:function(t){this._validate(t);var e=this._equals||n.equals;if(!e(t,this._value))if(this._state=ut,H())P(m(Et),this,t);else{this._value=t;var r=[];h(this,r),B(r),p(this)}return this},_get:function(){return H()?K(m(Et),this):this._value}}}function X(t,n){return t._uid=o(),t._children=[],t._state=ft,t._value=n,t._type=pt,t._equals=null,t}function Y(t){T(Et,new J,t)}function Z(t){return function(){var n,e=c(arguments,0),r=this;return Y(function(){n=t.apply(r,e)}),n}}function $(){Tt?Tt.refCount++:(Tt=q(Et,function(){return new J}),Tt.refCount=1);var t=!1;return{tick:function(){if(t)throw new Error("tyring to use ticker after release");Tt.tick()},release:function(){if(t)throw new Error("ticker already released");0===--Tt.refCount&&(Tt.stop(), | ||
Tt=null),t=!0}}}function tt(t){function e(t){if(o.isDerivable(t))return t.get();if(t instanceof Array)return t.map(e);if(t.constructor===Object){for(var n={},r=nt(t),i=r.length;i--;){var a=r[i];n[a]=e(t[a])}return n}return t}function i(t){return function(){var n=arguments;return o.derivation(function(){for(var e,r=0;n.length>r&&(e=o.unpack(n[r]),!t(e));r++);return e})}}function a(t){return t}function u(t){return function(n){return!t(n)}}t=n({},qt,t||{});var o={transact:Y,defaultEquals:r,setDebugMode:f,transaction:Z,ticker:$,Reactor:S,isAtom:function(t){return t&&(t._type===pt||t._type===vt)},isDerivable:function(t){return t&&(t._type===pt||t._type===vt||t._type===_t)},isDerivation:function(t){return t&&(t._type===_t||t._type===vt)},isLensed:function(t){return t&&t._type===vt},isReactor:function(t){return t&&t._type===dt}},l=z(o,t),h=L(o,t),p=n({},h,l,W(o,t)),_=n({},l,I(o,t)),v=n({},h,_,M(o,t));return o.atom=function(t){return X(Object.create(p),t)},o.atomic=function(t){return function(){var n,e=this,r=arguments;return o.atomically(function(){n=t.apply(e,r)}),n}},o.atomically=function(t){H()?t():o.transact(t)},o.derivation=function(t){return Q(Object.create(_),t)},o.derive=function(t){var n=c(arguments,1);return o.derivation(function(){for(var e="",r=0;t.length>r;r++)e+=t[r],n.length>r&&(e+=o.unpack(n[r]));return e})},o.lens=function(t){return U(Q(Object.create(v),t.get),t)},o.unpack=function(t){return o.isDerivable(t)?t.get():t},o.lift=function(t){return function(){var n=arguments,e=this;return o.derivation(function(){return t.apply(e,Array.prototype.map.call(n,o.unpack))})}},o.struct=function(t){if(t.constructor===Object||t instanceof Array)return o.derivation(function(){return e(t)});throw new Error("`struct` expects plain Object or Array")},o.or=i(a),o.mOr=i(s),o.and=i(u(a)),o.mAnd=i(u(s)),o}var nt=Object.keys,et=0,rt=Object.freeze({equals:function(){return!1}}),it=!1,at=0,ut=1,ot=2,ct=3,st=4,ft=5,lt=6,ht=[],pt="ATOM",_t="DERIVATION",vt="LENS",dt="REACTION",gt=0,yt=1,wt=3,mt={},kt="Cyclical Reactor Dependency! Not allowed!",bt=[]; | ||
n(S.prototype,{start:function(){return D(this._base),this},stop:function(){return O(this._base),this},force:function(){return C(this._base),this},isActive:function(){return this._base.active},orphan:function(){return R(this._base),this},adopt:function(t){if(t._type!==dt)throw Error("reactors can only adopt reactors");return V(this._base,t._base),this}}),n(F.prototype,S.prototype);var Et=y(),xt={push:function(){}};n(J.prototype,{onCommit:function(){var t,n,e=nt(this.inTxnValues);if(H())for(t=e.length;t--;)n=this.inTxnValues[e[t]],n[0].set(n[1]);else{for(t=e.length;t--;)n=this.inTxnValues[e[t]],n[0]._value=n[1],h(n[0],xt);for(B(this.reactorQueue),t=e.length;t--;)p(this.inTxnValues[e[t]][0])}},onAbort:function(){if(!H())for(var t=nt(this.inTxnValues),n=t.length;n--;)_(this.inTxnValues[t[n]][0])}});var Tt=null,qt={equals:r};n(t,tt()),t.withEquality=function(t){return tt({equals:t})},t["default"]=t}); | ||
!function(t,n){"use strict";t&&"function"==typeof t.define&&t.define.amd?t.define(["exports"],n):n("undefined"!=typeof exports?exports:t.Derivable={})}(this,function(t){"use strict";function n(t){for(var n=1;arguments.length>n;n++)for(var r=arguments[n],e=V(r),i=e.length;i--;){var o=e[i];t[o]=r[o]}return t}function r(t,n){return t===n?0!==t||1/t===1/n:t!==t&&n!==n}function e(t,n){return r(t,n)||t&&"function"==typeof t.equals&&t.equals(n)}function i(t,n){var r=t.indexOf(n);0>r&&t.push(n)}function o(t,n){var r=t.indexOf(n);r>=0&&t.splice(r,1)}function u(){return F++}function c(t,n){return Array.prototype.slice.call(t,n)}function a(t){return null!==t&&void 0!==t}function s(t){I=!!t}function f(t,n){return t._equals=n,t}function h(t){var n=z.length;z.push([]);try{return t(),z[n]}finally{z.pop()}}function l(t){if(z.length>0){var n=z[z.length-1];return n.push(t,0),n.length-1}return-1}function p(t,n){z.length>0&&(z[z.length-1][t]=n)}function _(){throw H}function v(t){this.parent=t,this.id2txnAtom={},this.globalEpoch=N,this.modifiedAtoms=[]}function d(){return null!==J}function g(t){y();try{t.call(null,_)}catch(n){if(E(),n!==H)throw n;return}m()}function y(){J=new v(J)}function m(){var t=J;J=t.parent;var n=[];t.modifiedAtoms.forEach(function(r){null!==J?r.set(t.id2txnAtom[r._id]._value):(r._set(t.id2txnAtom[r._id]._value),n.push(r._reactors))}),null===J?N=t.globalEpoch:J.globalEpoch=t.globalEpoch,n.forEach(function(t){t.forEach(function(t){t._maybeReact()})})}function E(){var t=J;J=t.parent,null===J?N=t.globalEpoch+1:J.globalEpoch=t.globalEpoch+1}function b(){y();var t=!1;return{tick:function(){if(t)throw new Error("can't tick disposed ticker");m(),y()},stop:function(){if(t)throw new Error("ticker already disposed");t=!0,m()},resetState:function(){if(t)throw new Error("ticker already disposed");E(),y()}}}function k(t,n){this._derivable=n,t&&(this.react=t),this._atoms=[],this._parent=null,this._active=!1,this._yielding=!1,this._reacting=!1,this._type=B,I&&(this.stack=Error().stack)}function w(t,n){if(t._type===L)i(n,t);else for(var r=0,e=t._lastParentsEpochs.length;e>r;r+=2)w(t._lastParentsEpochs[r],n); | ||
}function A(t,n){var r={derive:function(n,r,e,i,o){var u=this;switch(arguments.length){case 0:return u;case 1:switch(typeof n){case"function":return t.derivation(function(){return n(u.get())});case"string":case"number":return t.derivation(function(){return u.get()[t.unpack(n)]});default:if(n instanceof Array)return n.map(function(t){return u.derive(t)});if(n instanceof RegExp)return t.derivation(function(){return u.get().match(n)});if(t.isDerivable(n))return t.derivation(function(){var r=n.get(),e=u.get();switch(typeof r){case"function":return r(e);case"string":case"number":return e[r];default:if(r instanceof RegExp)return e.match(r);throw Error("type error")}return u.get()[t.unpack(n)]});throw Error("type error")}break;case 2:return t.derivation(function(){return n(u.get(),t.unpack(r))});case 3:return t.derivation(function(){return n(u.get(),t.unpack(r),t.unpack(e))});case 4:return t.derivation(function(){return n(u.get(),t.unpack(r),t.unpack(e),t.unpack(i))});case 5:return t.derivation(function(){return n(u.get(),t.unpack(r),t.unpack(e),t.unpack(i),t.unpack(o))});default:var a=[u].concat(c(arguments,1));return t.derivation(function(){return n.apply(null,a.map(t.unpack))})}},reactor:function(t){if("function"==typeof t)return new Q(t,this);if(t instanceof Q){if("function"!=typeof t.react)throw new Error("reactor missing .react method");return t._derivable=this,t}if(t&&t.react)return Object.assign(new Q(null,this),t);throw new Error("Unrecognized type for reactor "+t)},react:function(n,r){function e(n,r){if(!t.isDerivable(n))if("function"==typeof n)n=t.derivation(n);else{if("boolean"!=typeof n)throw Error("react "+r+" condition must be derivable");n=t.atom(n)}return n.derive(function(t){return!!t})}if("function"!=typeof n)throw Error("the first argument to .react must be a function");r=Object.assign({once:!1,from:!0,until:!1,when:!0,skipFirst:!1},r);var i=this.reactor({react:function(t){r.skipFirst?r.skipFirst=!1:(n(t),r.once&&(this.stop(),o.stop()))},onStart:r.onStart,onStop:r.onStop}),o=t.struct({until:e(r.until,"until"), | ||
when:e(r.when,"when")}).reactor(function(t){t.until?(i.stop(),this.stop()):t.when?i.isActive()||i.start().force():i.isActive()&&i.stop()});e(r.from,"from").reactor(function(t){t&&(o.start().force(),this.stop())}).start().force()},is:function(r){return t.lift(this._equals||n.equals)(this,r)},and:function(n){return this.derive(function(r){return r&&t.unpack(n)})},or:function(n){return this.derive(function(r){return r||t.unpack(n)})},then:function(n,r){return this.derive(function(e){return t.unpack(e?n:r)})},mThen:function(n,r){return this.derive(function(e){return t.unpack(a(e)?n:r)})},mOr:function(t){return this.mThen(this,t)},mDerive:function(t){if(1===arguments.length&&t instanceof Array){var n=this;return t.map(function(t){return n.mDerive(t)})}return this.mThen(this.derive.apply(this,arguments))},mAnd:function(t){return this.mThen(t,this)},not:function(){return this.derive(function(t){return!t})},withEquality:function(t){if(t){if("function"!=typeof t)throw new Error("equals must be function")}else t=null;return f(this._clone(),t)},__equals:function(t,r){return(this._equals||n.equals)(t,r)}};return r["switch"]=function(){var r=arguments;return this.derive(function(e){var i;for(i=0;r.length-1>i;i+=2)if(n.equals(e,t.unpack(r[i])))return t.unpack(r[i+1]);return i===r.length-1?t.unpack(r[i]):void 0})},r}function q(t,n){return{_clone:function(){return f(t.derivation(this._deriver),this._equals)},_forceEval:function(){var t=this,n=null,r=h(function(){if(I)try{n=t._deriver()}catch(r){throw console.error(t.stack),r}else n=t._deriver()});this.__equals(n,this._value)||this._epoch++,this._lastParentsEpochs=r,this._value=n},_update:function(){var t=null===J?N:J.globalEpoch;if(this._lastGlobalEpoch!==t){if(this._value===G)this._forceEval();else for(var n=0,r=this._lastParentsEpochs.length;r>n;n+=2){var e,i=this._lastParentsEpochs[n],o=this._lastParentsEpochs[n+1];if(i._type===L?e=i._getEpoch():(i._update(),e=i._epoch),e!==o)return void this._forceEval()}this._lastGlobalEpoch=t}},get:function(){var t=l(this);return this._update(), | ||
p(t,this._epoch),this._value}}}function O(t,n){return t._deriver=n,t._lastParentsEpochs=[],t._lastGlobalEpoch=N-1,t._epoch=0,t._type=M,t._value=G,t._equals=null,I&&(t.stack=Error().stack),t}function x(t,n){return{swap:function(t){var n=c(arguments,0);return n[0]=this.get(),this.set(t.apply(null,n))},lens:function(n){var r=this;return t.lens({get:function(){return n.get(r.get())},set:function(t){r.set(n.set(r.get(),t))}})}}}function D(t,n){return{_clone:function(){return f(t.lens(this._lensDescriptor),this._equals)},set:function(n){var r=this;return t.atomically(function(){r._lensDescriptor.set(n)}),this}}}function j(t,n){return t._lensDescriptor=n,t._type=U,t}function R(t,n){return{_clone:function(){return f(t.atom(this._value),this._equals)},set:function(t){if(null!==J){var n=void 0;void 0!==(n=J.id2txnAtom[this._id])&&t!==n._value?(J.globalEpoch++,n._epoch++,n._value=t):this.__equals(t,this._value)||(J.globalEpoch++,n=this._clone(),n._value=t,n._id=this._id,n._epoch=this._epoch+1,J.id2txnAtom[this._id]=n,i(J.modifiedAtoms,this))}else this.__equals(t,this._value)||(this._set(t),this._reactors.forEach(function(t){return t._maybeReact()}))},_set:function(t){N++,this._epoch++,this._value=t},get:function(){for(var t,n=J;null!==n;){if(t=n.id2txnAtom[this._id],void 0!==t)return p(l(this),t._epoch),t._value;n=n.parent}return p(l(this),this._epoch),this._value},_getEpoch:function(){for(var t,n=J;null!==n;){if(t=n.id2txnAtom[this._id],void 0!==t)return t._epoch;n=n.parent}return this._epoch}}}function S(t,n){return t._id=u(),t._reactors=[],t._epoch=0,t._value=n,t._type=L,t._equals=null,t}function P(t){return function(){var n,r=c(arguments,0),e=this;return g(function(){n=t.apply(e,r)}),n}}function T(){W?W.refCount++:(W=b(),W.refCount=1);var t=!1;return{tick:function(){if(t)throw new Error("tyring to use ticker after release");W.tick()},release:function(){if(t)throw new Error("ticker already released");0===--W.refCount&&(W.stop(),W=null),t=!0}}}function C(t){function r(t){if(f.isDerivable(t))return t.get();if(t instanceof Array)return t.map(r); | ||
if(t.constructor===Object){for(var n={},e=V(t),i=e.length;i--;){var o=e[i];n[o]=r(t[o])}return n}return t}function i(t){return function(){var n=arguments;return f.derivation(function(){for(var r,e=0;n.length>e&&(r=f.unpack(n[e]),!t(r));e++);return r})}}function o(t){return t}function u(t){return function(n){return!t(n)}}t=n({},X,t||{});var f={transact:g,defaultEquals:e,setDebugMode:s,transaction:P,ticker:T,Reactor:Q,isAtom:function(t){return t&&(t._type===L||t._type===U)},isDerivable:function(t){return t&&(t._type===L||t._type===U||t._type===M)},isDerivation:function(t){return t&&(t._type===M||t._type===U)},isLensed:function(t){return t&&t._type===U},isReactor:function(t){return t&&t._type===B}},h=A(f,t),l=x(f,t),p=n({},l,h,R(f,t)),_=n({},h,q(f,t)),v=n({},l,_,D(f,t));return f.atom=function(t){return S(Object.create(p),t)},f.atomic=function(t){return function(){var n,r=this,e=arguments;return f.atomically(function(){n=t.apply(r,e)}),n}},f.atomically=function(t){d()?t():f.transact(t)},f.derivation=function(t){return O(Object.create(_),t)},f.derive=function(t){var n=c(arguments,1);return f.derivation(function(){for(var r="",e=0;t.length>e;e++)r+=t[e],n.length>e&&(r+=f.unpack(n[e]));return r})},f.lens=function(t){return j(O(Object.create(v),t.get),t)},f.unpack=function(t){return f.isDerivable(t)?t.get():t},f.lift=function(t){return function(){var n=arguments,r=this;return f.derivation(function(){return t.apply(r,Array.prototype.map.call(n,f.unpack))})}},f.struct=function(t){if(t.constructor===Object||t instanceof Array)return f.derivation(function(){return r(t)});throw new Error("`struct` expects plain Object or Array")},f.or=i(o),f.mOr=i(a),f.and=i(u(o)),f.mAnd=i(u(a)),f}var V=Object.keys,F=0,G=Object.freeze({equals:function(){return!1}}),I=!1,N=0,z=[],L="ATOM",M="DERIVATION",U="LENS",B="REACTION",H={},J=null,K=[],Q=k;Object.assign(Q.prototype,{start:function(){this._lastValue=this._derivable.get(),this._lastEpoch=this._derivable._epoch,this._atoms=[],w(this._derivable,this._atoms);var t=this;this._atoms.forEach(function(n){ | ||
i(n._reactors,t)});var n=K.length;return n>0&&(this._parent=K[n-1]),this._active=!0,this.onStart&&this.onStart(),this},_force:function(t){try{K.push(this),this._reacting=!0,this.react(t);var n=this._atoms,r=[];this._atoms=r,w(this._derivable,r);var e=this;r.forEach(function(t){var r=n.indexOf(t);-1===r?i(t._reactors,e):n[r]=null}),n.forEach(function(t){null!==t&&o(t._reactors,e)})}catch(u){throw I&&console.error(this.stack),u}finally{this._reacting=!1,K.pop()}},force:function(){return this._force(this._derivable.get()),this},_maybeReact:function(){if(this._reacting)throw Error("cyclical update detected!!");if(this._active){if(this._yielding)throw Error("reactor dependency cycle detected");null!==this._parent&&(this._yielding=!0,this._parent._maybeReact(),this._yielding=!1);var t=this._derivable.get();this._derivable._epoch===this._lastEpoch||this._derivable.__equals(t,this._lastValue)||this._force(t),this._lastEpoch=this._derivable._epoch,this._lastValue=t}},stop:function(){var t=this;return this._atoms.forEach(function(n){return o(n._reactors,t)}),this._atoms=[],this._parent=null,this._active=!1,this.onStop&&this.onStop(),this},orphan:function(){return this._parent=null,this},adopt:function(t){return t._parent=this,this},isActive:function(){return this._active}});var W=null,X={equals:e};n(t,C()),t.withEquality=function(t){return C({equals:t})},t["default"]=t}); | ||
//# sourceMappingURL=derivable.min.js.map |
{ | ||
"name": "derivable", | ||
"version": "0.12.1", | ||
"version": "0.13.0-beta2", | ||
"description": "Functional Reactive State for JavaScript & TypeScript", | ||
@@ -5,0 +5,0 @@ "author": "David Sheldrick", |
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
170095
1083