Socket
Socket
Sign inDemoInstall

@nx-js/observer-util

Package Overview
Dependencies
0
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.1 to 4.1.0

types/index.d.ts

302

dist/cjs.es5.js

@@ -6,2 +6,3 @@ 'use strict';

var connectionStore = new WeakMap();
var ITERATION_KEY = Symbol('iteration key');

@@ -13,26 +14,52 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
var reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
if (type === 'iterate') {
key = ITERATION_KEY;
}
var reactionsForObj = connectionStore.get(target);
var reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
var reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation(ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
var reactionsForTarget = connectionStore.get(target);
var reactionsForKey = new Set();
if (type === 'clear') {
for (var key$1 in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key$1);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
var iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
var reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -42,3 +69,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -53,5 +80,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(("Unobserved reactions can not be executed. You tried to run a reaction for " + fn));
return fn.apply(context, args);
}

@@ -62,3 +89,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -77,14 +103,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -109,21 +141,9 @@ if (typeof reaction.scheduler === 'function') {

if (typeof fn !== 'function') {
throw new TypeError(("The first argument must be a function instead of " + fn));
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(("The second argument must be an options object instead of " + options));
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
var reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -138,22 +158,3 @@ reaction[IS_REACTION] = true;

function validateOptions(ref) {
var lazy = ref.lazy; if ( lazy === void 0 ) lazy = false;
var scheduler = ref.scheduler;
if (typeof lazy !== 'boolean') {
throw new TypeError(("options.lazy must be a boolean or undefined instead of " + lazy));
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(("options.scheduler must be a function, an object or undefined instead of " + scheduler));
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(("The first argument must be a reaction instead of " + reaction));
}
// do nothing, if the reaction is already unobserved

@@ -175,27 +176,26 @@ if (!reaction.unobserved) {

var ITERATE = Symbol('iterate');
var getPrototypeOf = Object.getPrototypeOf;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var instrumentations = {
has: function has(value) {
var rawContext = proxyToRaw.get(this);
has: function has(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return proto.has.apply(target, arguments);
},
get: function get(key) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'get' });
return proto.get.apply(target, arguments);
},
add: function add(value) {
var rawContext = proxyToRaw.get(this);
add: function add(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
var valueChanged = !proto.has.call(rawContext, value);
var result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: key, type: 'add' });
}

@@ -205,22 +205,24 @@ return result;

set: function set(key, value) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
var valueChanged = proto.get.call(rawContext, key) !== value;
var result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target: target, key: key, value: value, oldValue: oldValue, type: 'set' });
}
return result;
},
delete: function delete$1(value) {
var rawContext = proxyToRaw.get(this);
delete: function delete$1(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
var valueChanged = proto.has.call(rawContext, value);
var result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -230,9 +232,10 @@ return result;

clear: function clear() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadItems = target.size !== 0;
var oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
var valueChanged = rawContext.size !== 0;
var result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
var result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target: target, oldTarget: oldTarget, type: 'clear' });
}

@@ -242,37 +245,37 @@ return result;

forEach: function forEach() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys: function keys() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values: function values() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries: function entries() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
get size() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}
};
instrumentations[Symbol.iterator] = function () {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
};

@@ -283,3 +286,3 @@

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -309,7 +312,7 @@ }

var ENUMERATE = Symbol('enumerate');
var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
var result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
var result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -319,6 +322,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target: target, key: key, receiver: receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -333,9 +334,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
var result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -345,10 +357,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
var hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
var valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
var prevLength = Array.isArray(obj) && obj.length;
var oldValue = target[key];
// execute the set operation before running any reaction
var result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
var lengthChanged = prevLength !== false && prevLength !== obj.length;
var result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -360,29 +370,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, receiver: receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target: target,
key: key,
value: value,
oldValue: oldValue,
receiver: receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
var hadKey = key in obj;
var hadKey = hasOwnProperty$1.call(target, key);
var oldValue = target[key];
// execute the delete operation before running any reaction
var result = Reflect.deleteProperty(obj, key);
var result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -392,3 +407,3 @@ return result;

var baseHandlers = { get: get, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };
var baseHandlers = { get: get, has: has, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };

@@ -398,5 +413,2 @@ function observable(obj) {

if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -403,0 +415,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

'use strict';Object.defineProperty(exports,'__esModule',{value:!0});var connectionStore=new WeakMap;function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForKey(a,b,c){var d=connectionStore.get(a),e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function iterateReactionsForKey(a,b,c){var d=connectionStore.get(a)[b];d&&Array.from(d).forEach(c)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=void 0}function releaseReactionKeyConnection(a){a.delete(this)}var runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)throw new Error('Unobserved reactions can not be executed. You tried to run a reaction for '+b);releaseReaction(a),a.cleaners=[];try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForKey(a,b){runningReaction&&registerReactionForKey(a,b,runningReaction)}function queueReactionsForKey(a,b){iterateReactionsForKey(a,b,queueReaction)}function queueReaction(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}var IS_REACTION=Symbol('is reaction');function observe(a,b){function c(){return runAsReaction(c,a,this,arguments)}if(void 0===b&&(b={}),'function'!=typeof a)throw new TypeError('The first argument must be a function instead of '+a);if(a[IS_REACTION])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError('The second argument must be an options object instead of '+b);return validateOptions(b),c.scheduler=b.scheduler,c.runId=0,c[IS_REACTION]=!0,b.lazy||c(),c}function validateOptions(a){var b=a.lazy;void 0===b&&(b=!1);var c=a.scheduler;if('boolean'!=typeof b)throw new TypeError('options.lazy must be a boolean or undefined instead of '+b);if('object'==typeof c&&null!==c){if('function'!=typeof c.add||'function'!=typeof c.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==c&&'function'!=typeof c)throw new TypeError('options.scheduler must be a function, an object or undefined instead of '+c)}function unobserve(a){if('function'!=typeof a||!a[IS_REACTION])throw new TypeError('The first argument must be a reaction instead of '+a);a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}var proxyToRaw=new WeakMap,rawToProxy=new WeakMap,ITERATE=Symbol('iterate'),getPrototypeOf=Object.getPrototypeOf,instrumentations={has:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForKey(c,b),d.has.apply(c,arguments)},get:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForKey(c,b),d.get.apply(c,arguments)},add:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=!d.has.call(c,b),f=d.add.apply(c,arguments);return e&&(queueReactionsForKey(c,b),queueReactionsForKey(c,ITERATE)),f},set:function a(b,c){var d=proxyToRaw.get(this),e=getPrototypeOf(this),f=e.get.call(d,b)!==c,g=e.set.apply(d,arguments);return f&&(queueReactionsForKey(d,b),queueReactionsForKey(d,ITERATE)),g},delete:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.delete.apply(c,arguments);return e&&(queueReactionsForKey(c,b),queueReactionsForKey(c,ITERATE)),f},clear:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this),d=0!==b.size,e=c.clear.apply(b,arguments);return d&&queueReactionsForKey(b,ITERATE),e},forEach:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.forEach.apply(b,arguments)},keys:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.keys.apply(b,arguments)},values:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.values.apply(b,arguments)},entries:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.entries.apply(b,arguments)},get size(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),Reflect.get(b,'size',a)}};instrumentations[Symbol.iterator]=function(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b[Symbol.iterator].apply(a,arguments)};var collectionHandlers={get:function a(b,c,d){return b=c in getPrototypeOf(b)?instrumentations:b,Reflect.get(b,c,d)}},dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}var ENUMERATE=Symbol('enumerate');function get(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=proxyToRaw.get(a)||a,registerRunningReactionForKey(a,b),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function ownKeys(a){return registerRunningReactionForKey(a,ENUMERATE),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);var e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return hasRunningReaction()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):a===proxyToRaw.get(d)?('symbol'!=typeof b&&e&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),h&&queueReactionsForKey(a,'length'),g):g}function deleteProperty(a,b){var c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),d}var baseHandlers={get:get,ownKeys:ownKeys,set:set,deleteProperty:deleteProperty};function observable(a){if(void 0===a&&(a={}),'object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){var b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}exports.observe=observe,exports.unobserve=unobserve,exports.observable=observable,exports.isObservable=isObservable,exports.raw=raw;
'use strict';Object.defineProperty(exports,'__esModule',{value:!0});var connectionStore=new WeakMap,ITERATION_KEY=Symbol('iteration key');function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForOperation(a,b){var c=b.target,d=b.key,e=b.type;'iterate'===e&&(d=ITERATION_KEY);var f=connectionStore.get(c),g=f[d];g||(f[d]=g=new Set),g.has(a)||(g.add(a),a.cleaners.push(g))}function getReactionsForOperation(a){var b=a.target,c=a.key,d=a.type,e=connectionStore.get(b),f=new Set;if('clear'===d)for(var g in e)addReactionsForKey(f,e,g);else addReactionsForKey(f,e,c);if('add'===d||'delete'===d||'clear'===d){var h=Array.isArray(b)?'length':ITERATION_KEY;addReactionsForKey(f,e,h)}return f}function addReactionsForKey(a,b,c){var d=b[c];d&&d.forEach(a.add,a)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=[]}function releaseReactionKeyConnection(a){a.delete(this)}var runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)return b.apply(c,d);releaseReaction(a);try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForOperation(a){runningReaction&&(runningReaction.debugger&&runningReaction.debugger(a),registerReactionForOperation(runningReaction,a))}function queueReactionsForOperation(a){getReactionsForOperation(a).forEach(queueReaction,a)}function queueReaction(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}var IS_REACTION=Symbol('is reaction');function observe(a,b){void 0===b&&(b={});var c=a[IS_REACTION]?a:function b(){return runAsReaction(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[IS_REACTION]=!0,b.lazy||c(),c}function unobserve(a){a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}var proxyToRaw=new WeakMap,rawToProxy=new WeakMap,getPrototypeOf=Object.getPrototypeOf,hasOwnProperty=Object.prototype.hasOwnProperty,instrumentations={has:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForOperation({target:c,key:b,type:'has'}),d.has.apply(c,arguments)},get:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForOperation({target:c,key:b,type:'get'}),d.get.apply(c,arguments)},add:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.add.apply(c,arguments);return e||queueReactionsForOperation({target:c,key:b,value:b,type:'add'}),f},set:function a(b,c){var d=proxyToRaw.get(this),e=getPrototypeOf(this),f=e.has.call(d,b),g=e.get.call(d,b),h=e.set.apply(d,arguments);return f?c!==g&&queueReactionsForOperation({target:d,key:b,value:c,oldValue:g,type:'set'}):queueReactionsForOperation({target:d,key:b,value:c,type:'add'}),h},delete:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.get?d.get.call(c,b):void 0,g=d.delete.apply(c,arguments);return e&&queueReactionsForOperation({target:c,key:b,oldValue:f,type:'delete'}),g},clear:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this),d=0!==b.size,e=b instanceof Map?new Map(b):new Set(b),f=c.clear.apply(b,arguments);return d&&queueReactionsForOperation({target:b,oldTarget:e,type:'clear'}),f},forEach:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.forEach.apply(b,arguments)},keys:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.keys.apply(b,arguments)},values:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.values.apply(b,arguments)},entries:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.entries.apply(b,arguments)},get size(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};instrumentations[Symbol.iterator]=function(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)};var collectionHandlers={get:function a(b,c,d){return b=hasOwnProperty.call(instrumentations,c)?instrumentations:b,Reflect.get(b,c,d)}},dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}var hasOwnProperty$1=Object.prototype.hasOwnProperty;function get(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(registerRunningReactionForOperation({target:a,key:b,receiver:c,type:'get'}),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function has(a,b){var c=Reflect.has(a,b);return'symbol'==typeof b?c:(registerRunningReactionForOperation({target:a,key:b,type:'has'}),c)}function ownKeys(a){return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);var e=hasOwnProperty$1.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return hasRunningReaction()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):'symbol'==typeof b||a!==proxyToRaw.get(d)?g:(e?c!==f&&queueReactionsForOperation({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):queueReactionsForOperation({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function deleteProperty(a,b){var c=hasOwnProperty$1.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&queueReactionsForOperation({target:a,key:b,oldValue:d,type:'delete'}),e}var baseHandlers={get:get,has:has,ownKeys:ownKeys,set:set,deleteProperty:deleteProperty};function observable(a){return void 0===a&&(a={}),proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){var b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}exports.observe=observe,exports.unobserve=unobserve,exports.observable=observable,exports.isObservable=isObservable,exports.raw=raw;

@@ -6,2 +6,3 @@ 'use strict';

const connectionStore = new WeakMap();
const ITERATION_KEY = Symbol('iteration key');

@@ -13,26 +14,44 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
const reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, { target, key, type }) {
if (type === 'iterate') {
key = ITERATION_KEY;
}
const reactionsForObj = connectionStore.get(target);
let reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
const reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation({ target, key, type }) {
const reactionsForTarget = connectionStore.get(target);
const reactionsForKey = new Set();
if (type === 'clear') {
for (let key in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
const iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
const reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -42,3 +61,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -53,5 +72,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${fn}`);
return fn.apply(context, args);
}

@@ -62,3 +81,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -77,14 +95,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -107,21 +131,9 @@ if (typeof reaction.scheduler === 'function') {

function observe(fn, options = {}) {
if (typeof fn !== 'function') {
throw new TypeError(`The first argument must be a function instead of ${fn}`);
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(`The second argument must be an options object instead of ${options}`);
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
const reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -136,19 +148,3 @@ reaction[IS_REACTION] = true;

function validateOptions({ lazy = false, scheduler }) {
if (typeof lazy !== 'boolean') {
throw new TypeError(`options.lazy must be a boolean or undefined instead of ${lazy}`);
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${scheduler}`);
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(`The first argument must be a reaction instead of ${reaction}`);
}
// do nothing, if the reaction is already unobserved

@@ -170,27 +166,26 @@ if (!reaction.unobserved) {

const ITERATE = Symbol('iterate');
const getPrototypeOf = Object.getPrototypeOf;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const instrumentations = {
has(value) {
const rawContext = proxyToRaw.get(this);
has(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'has' });
return proto.has.apply(target, arguments);
},
get(key) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'get' });
return proto.get.apply(target, arguments);
},
add(value) {
const rawContext = proxyToRaw.get(this);
add(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
const valueChanged = !proto.has.call(rawContext, value);
const result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value: key, type: 'add' });
}

@@ -200,22 +195,24 @@ return result;

set(key, value) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
const valueChanged = proto.get.call(rawContext, key) !== value;
const result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target, key, value, oldValue, type: 'set' });
}
return result;
},
delete(value) {
const rawContext = proxyToRaw.get(this);
delete(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
const valueChanged = proto.has.call(rawContext, value);
const result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -225,9 +222,10 @@ return result;

clear() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadItems = target.size !== 0;
const oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
const valueChanged = rawContext.size !== 0;
const result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
const result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target, oldTarget, type: 'clear' });
}

@@ -237,36 +235,36 @@ return result;

forEach() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
[Symbol.iterator]() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
},
get size() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}

@@ -278,3 +276,3 @@ };

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -304,7 +302,7 @@ }

const ENUMERATE = Symbol('enumerate');
const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
const result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
const result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -314,6 +312,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target, key, receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -328,9 +324,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
const result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target, key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -340,10 +347,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
const hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
const valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
const prevLength = Array.isArray(obj) && obj.length;
const oldValue = target[key];
// execute the set operation before running any reaction
const result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
const lengthChanged = prevLength !== false && prevLength !== obj.length;
const result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -355,29 +360,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target, key, value, receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target,
key,
value,
oldValue,
receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
const hadKey = key in obj;
const hadKey = hasOwnProperty$1.call(target, key);
const oldValue = target[key];
// execute the delete operation before running any reaction
const result = Reflect.deleteProperty(obj, key);
const result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -387,8 +397,5 @@ return result;

var baseHandlers = { get, ownKeys, set, deleteProperty };
var baseHandlers = { get, has, ownKeys, set, deleteProperty };
function observable(obj = {}) {
if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -395,0 +402,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

'use strict';Object.defineProperty(exports,'__esModule',{value:!0});const connectionStore=new WeakMap;function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForKey(a,b,c){const d=connectionStore.get(a);let e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function iterateReactionsForKey(a,b,c){const d=connectionStore.get(a)[b];d&&Array.from(d).forEach(c)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=void 0}function releaseReactionKeyConnection(a){a.delete(this)}let runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${b}`);releaseReaction(a),a.cleaners=[];try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForKey(a,b){runningReaction&&registerReactionForKey(a,b,runningReaction)}function queueReactionsForKey(a,b){iterateReactionsForKey(a,b,queueReaction)}function queueReaction(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}const IS_REACTION=Symbol('is reaction');function observe(a,b={}){function c(){return runAsReaction(c,a,this,arguments)}if('function'!=typeof a)throw new TypeError(`The first argument must be a function instead of ${a}`);if(a[IS_REACTION])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError(`The second argument must be an options object instead of ${b}`);return validateOptions(b),c.scheduler=b.scheduler,c.runId=0,c[IS_REACTION]=!0,b.lazy||c(),c}function validateOptions({lazy:b=!1,scheduler:a}){if('boolean'!=typeof b)throw new TypeError(`options.lazy must be a boolean or undefined instead of ${b}`);if('object'==typeof a&&null!==a){if('function'!=typeof a.add||'function'!=typeof a.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==a&&'function'!=typeof a)throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${a}`)}function unobserve(a){if('function'!=typeof a||!a[IS_REACTION])throw new TypeError(`The first argument must be a reaction instead of ${a}`);a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}const proxyToRaw=new WeakMap,rawToProxy=new WeakMap,ITERATE=Symbol('iterate'),getPrototypeOf=Object.getPrototypeOf,instrumentations={has(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,a),c.has.apply(b,arguments)},get(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,a),c.get.apply(b,arguments)},add(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=!c.has.call(b,a),e=c.add.apply(b,arguments);return d&&(queueReactionsForKey(b,a),queueReactionsForKey(b,ITERATE)),e},set(a,b){const c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.get.call(c,a)!==b,f=d.set.apply(c,arguments);return e&&(queueReactionsForKey(c,a),queueReactionsForKey(c,ITERATE)),f},delete(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.delete.apply(b,arguments);return d&&(queueReactionsForKey(b,a),queueReactionsForKey(b,ITERATE)),e},clear(){const a=proxyToRaw.get(this),b=getPrototypeOf(this),c=0!==a.size,d=b.clear.apply(a,arguments);return c&&queueReactionsForKey(a,ITERATE),d},forEach(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.forEach.apply(a,arguments)},keys(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.keys.apply(a,arguments)},values(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.values.apply(a,arguments)},entries(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b[Symbol.iterator].apply(a,arguments)},get size(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),Reflect.get(b,'size',a)}};var collectionHandlers={get(a,b,c){return a=b in getPrototypeOf(a)?instrumentations:a,Reflect.get(a,b,c)}};const dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}const ENUMERATE=Symbol('enumerate');function get(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=proxyToRaw.get(a)||a,registerRunningReactionForKey(a,b),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function ownKeys(a){return registerRunningReactionForKey(a,ENUMERATE),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);const e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return hasRunningReaction()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):a===proxyToRaw.get(d)?('symbol'!=typeof b&&e&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),h&&queueReactionsForKey(a,'length'),g):g}function deleteProperty(a,b){const c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),d}var baseHandlers={get,ownKeys,set,deleteProperty};function observable(a={}){if('object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){const b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}exports.observe=observe,exports.unobserve=unobserve,exports.observable=observable,exports.isObservable=isObservable,exports.raw=raw;
'use strict';Object.defineProperty(exports,'__esModule',{value:!0});const connectionStore=new WeakMap,ITERATION_KEY=Symbol('iteration key');function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForOperation(a,{target:b,key:c,type:d}){'iterate'===d&&(c=ITERATION_KEY);const e=connectionStore.get(b);let f=e[c];f||(e[c]=f=new Set),f.has(a)||(f.add(a),a.cleaners.push(f))}function getReactionsForOperation({target:a,key:b,type:c}){const d=connectionStore.get(a),e=new Set;if('clear'===c)for(let a in d)addReactionsForKey(e,d,a);else addReactionsForKey(e,d,b);if('add'===c||'delete'===c||'clear'===c){const b=Array.isArray(a)?'length':ITERATION_KEY;addReactionsForKey(e,d,b)}return e}function addReactionsForKey(a,b,c){const d=b[c];d&&d.forEach(a.add,a)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=[]}function releaseReactionKeyConnection(a){a.delete(this)}let runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)return b.apply(c,d);releaseReaction(a);try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForOperation(a){runningReaction&&(runningReaction.debugger&&runningReaction.debugger(a),registerReactionForOperation(runningReaction,a))}function queueReactionsForOperation(a){getReactionsForOperation(a).forEach(queueReaction,a)}function queueReaction(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}const IS_REACTION=Symbol('is reaction');function observe(a,b={}){const c=a[IS_REACTION]?a:function b(){return runAsReaction(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[IS_REACTION]=!0,b.lazy||c(),c}function unobserve(a){a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}const proxyToRaw=new WeakMap,rawToProxy=new WeakMap,getPrototypeOf=Object.getPrototypeOf,hasOwnProperty=Object.prototype.hasOwnProperty,instrumentations={has(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,key:a,type:'has'}),c.has.apply(b,arguments)},get(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,key:a,type:'get'}),c.get.apply(b,arguments)},add(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.add.apply(b,arguments);return d||queueReactionsForOperation({target:b,key:a,value:a,type:'add'}),e},set(a,b){const c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,a),f=d.get.call(c,a),g=d.set.apply(c,arguments);return e?b!==f&&queueReactionsForOperation({target:c,key:a,value:b,oldValue:f,type:'set'}):queueReactionsForOperation({target:c,key:a,value:b,type:'add'}),g},delete(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.get?c.get.call(b,a):void 0,f=c.delete.apply(b,arguments);return d&&queueReactionsForOperation({target:b,key:a,oldValue:e,type:'delete'}),f},clear(){const a=proxyToRaw.get(this),b=getPrototypeOf(this),c=0!==a.size,d=a instanceof Map?new Map(a):new Set(a),e=b.clear.apply(a,arguments);return c&&queueReactionsForOperation({target:a,oldTarget:d,type:'clear'}),e},forEach(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.forEach.apply(a,arguments)},keys(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.keys.apply(a,arguments)},values(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.values.apply(a,arguments)},entries(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)},get size(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};var collectionHandlers={get(a,b,c){return a=hasOwnProperty.call(instrumentations,b)?instrumentations:a,Reflect.get(a,b,c)}};const dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}const hasOwnProperty$1=Object.prototype.hasOwnProperty;function get(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(registerRunningReactionForOperation({target:a,key:b,receiver:c,type:'get'}),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function has(a,b){const c=Reflect.has(a,b);return'symbol'==typeof b?c:(registerRunningReactionForOperation({target:a,key:b,type:'has'}),c)}function ownKeys(a){return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);const e=hasOwnProperty$1.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return hasRunningReaction()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):'symbol'==typeof b||a!==proxyToRaw.get(d)?g:(e?c!==f&&queueReactionsForOperation({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):queueReactionsForOperation({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function deleteProperty(a,b){const c=hasOwnProperty$1.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&queueReactionsForOperation({target:a,key:b,oldValue:d,type:'delete'}),e}var baseHandlers={get,has,ownKeys,set,deleteProperty};function observable(a={}){return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){const b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}exports.observe=observe,exports.unobserve=unobserve,exports.observable=observable,exports.isObservable=isObservable,exports.raw=raw;
var connectionStore = new WeakMap();
var ITERATION_KEY = Symbol('iteration key');

@@ -8,26 +9,52 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
var reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
if (type === 'iterate') {
key = ITERATION_KEY;
}
var reactionsForObj = connectionStore.get(target);
var reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
var reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation(ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
var reactionsForTarget = connectionStore.get(target);
var reactionsForKey = new Set();
if (type === 'clear') {
for (var key$1 in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key$1);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
var iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
var reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -37,3 +64,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -48,5 +75,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(("Unobserved reactions can not be executed. You tried to run a reaction for " + fn));
return fn.apply(context, args);
}

@@ -57,3 +84,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -72,14 +98,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -104,21 +136,9 @@ if (typeof reaction.scheduler === 'function') {

if (typeof fn !== 'function') {
throw new TypeError(("The first argument must be a function instead of " + fn));
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(("The second argument must be an options object instead of " + options));
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
var reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -133,22 +153,3 @@ reaction[IS_REACTION] = true;

function validateOptions(ref) {
var lazy = ref.lazy; if ( lazy === void 0 ) lazy = false;
var scheduler = ref.scheduler;
if (typeof lazy !== 'boolean') {
throw new TypeError(("options.lazy must be a boolean or undefined instead of " + lazy));
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(("options.scheduler must be a function, an object or undefined instead of " + scheduler));
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(("The first argument must be a reaction instead of " + reaction));
}
// do nothing, if the reaction is already unobserved

@@ -170,27 +171,26 @@ if (!reaction.unobserved) {

var ITERATE = Symbol('iterate');
var getPrototypeOf = Object.getPrototypeOf;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var instrumentations = {
has: function has(value) {
var rawContext = proxyToRaw.get(this);
has: function has(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return proto.has.apply(target, arguments);
},
get: function get(key) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'get' });
return proto.get.apply(target, arguments);
},
add: function add(value) {
var rawContext = proxyToRaw.get(this);
add: function add(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
var valueChanged = !proto.has.call(rawContext, value);
var result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: key, type: 'add' });
}

@@ -200,22 +200,24 @@ return result;

set: function set(key, value) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
var valueChanged = proto.get.call(rawContext, key) !== value;
var result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target: target, key: key, value: value, oldValue: oldValue, type: 'set' });
}
return result;
},
delete: function delete$1(value) {
var rawContext = proxyToRaw.get(this);
delete: function delete$1(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
var valueChanged = proto.has.call(rawContext, value);
var result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -225,9 +227,10 @@ return result;

clear: function clear() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadItems = target.size !== 0;
var oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
var valueChanged = rawContext.size !== 0;
var result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
var result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target: target, oldTarget: oldTarget, type: 'clear' });
}

@@ -237,37 +240,37 @@ return result;

forEach: function forEach() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys: function keys() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values: function values() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries: function entries() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
get size() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}
};
instrumentations[Symbol.iterator] = function () {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
};

@@ -278,3 +281,3 @@

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -304,7 +307,7 @@ }

var ENUMERATE = Symbol('enumerate');
var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
var result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
var result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -314,6 +317,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target: target, key: key, receiver: receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -328,9 +329,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
var result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -340,10 +352,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
var hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
var valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
var prevLength = Array.isArray(obj) && obj.length;
var oldValue = target[key];
// execute the set operation before running any reaction
var result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
var lengthChanged = prevLength !== false && prevLength !== obj.length;
var result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -355,29 +365,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, receiver: receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target: target,
key: key,
value: value,
oldValue: oldValue,
receiver: receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
var hadKey = key in obj;
var hadKey = hasOwnProperty$1.call(target, key);
var oldValue = target[key];
// execute the delete operation before running any reaction
var result = Reflect.deleteProperty(obj, key);
var result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -387,3 +402,3 @@ return result;

var baseHandlers = { get: get, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };
var baseHandlers = { get: get, has: has, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };

@@ -393,5 +408,2 @@ function observable(obj) {

if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -398,0 +410,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

var connectionStore=new WeakMap;function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForKey(a,b,c){var d=connectionStore.get(a),e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function iterateReactionsForKey(a,b,c){var d=connectionStore.get(a)[b];d&&Array.from(d).forEach(c)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=void 0}function releaseReactionKeyConnection(a){a.delete(this)}var runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)throw new Error('Unobserved reactions can not be executed. You tried to run a reaction for '+b);releaseReaction(a),a.cleaners=[];try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForKey(a,b){runningReaction&&registerReactionForKey(a,b,runningReaction)}function queueReactionsForKey(a,b){iterateReactionsForKey(a,b,queueReaction)}function queueReaction(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}var IS_REACTION=Symbol('is reaction');function observe(a,b){function c(){return runAsReaction(c,a,this,arguments)}if(void 0===b&&(b={}),'function'!=typeof a)throw new TypeError('The first argument must be a function instead of '+a);if(a[IS_REACTION])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError('The second argument must be an options object instead of '+b);return validateOptions(b),c.scheduler=b.scheduler,c.runId=0,c[IS_REACTION]=!0,b.lazy||c(),c}function validateOptions(a){var b=a.lazy;void 0===b&&(b=!1);var c=a.scheduler;if('boolean'!=typeof b)throw new TypeError('options.lazy must be a boolean or undefined instead of '+b);if('object'==typeof c&&null!==c){if('function'!=typeof c.add||'function'!=typeof c.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==c&&'function'!=typeof c)throw new TypeError('options.scheduler must be a function, an object or undefined instead of '+c)}function unobserve(a){if('function'!=typeof a||!a[IS_REACTION])throw new TypeError('The first argument must be a reaction instead of '+a);a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}var proxyToRaw=new WeakMap,rawToProxy=new WeakMap,ITERATE=Symbol('iterate'),getPrototypeOf=Object.getPrototypeOf,instrumentations={has:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForKey(c,b),d.has.apply(c,arguments)},get:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForKey(c,b),d.get.apply(c,arguments)},add:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=!d.has.call(c,b),f=d.add.apply(c,arguments);return e&&(queueReactionsForKey(c,b),queueReactionsForKey(c,ITERATE)),f},set:function a(b,c){var d=proxyToRaw.get(this),e=getPrototypeOf(this),f=e.get.call(d,b)!==c,g=e.set.apply(d,arguments);return f&&(queueReactionsForKey(d,b),queueReactionsForKey(d,ITERATE)),g},delete:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.delete.apply(c,arguments);return e&&(queueReactionsForKey(c,b),queueReactionsForKey(c,ITERATE)),f},clear:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this),d=0!==b.size,e=c.clear.apply(b,arguments);return d&&queueReactionsForKey(b,ITERATE),e},forEach:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.forEach.apply(b,arguments)},keys:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.keys.apply(b,arguments)},values:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.values.apply(b,arguments)},entries:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,ITERATE),c.entries.apply(b,arguments)},get size(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),Reflect.get(b,'size',a)}};instrumentations[Symbol.iterator]=function(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b[Symbol.iterator].apply(a,arguments)};var collectionHandlers={get:function a(b,c,d){return b=c in getPrototypeOf(b)?instrumentations:b,Reflect.get(b,c,d)}},dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}var ENUMERATE=Symbol('enumerate');function get(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=proxyToRaw.get(a)||a,registerRunningReactionForKey(a,b),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function ownKeys(a){return registerRunningReactionForKey(a,ENUMERATE),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);var e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return hasRunningReaction()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):a===proxyToRaw.get(d)?('symbol'!=typeof b&&e&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),h&&queueReactionsForKey(a,'length'),g):g}function deleteProperty(a,b){var c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),d}var baseHandlers={get:get,ownKeys:ownKeys,set:set,deleteProperty:deleteProperty};function observable(a){if(void 0===a&&(a={}),'object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){var b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}export{observe,unobserve,observable,isObservable,raw};
var connectionStore=new WeakMap,ITERATION_KEY=Symbol('iteration key');function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForOperation(a,b){var c=b.target,d=b.key,e=b.type;'iterate'===e&&(d=ITERATION_KEY);var f=connectionStore.get(c),g=f[d];g||(f[d]=g=new Set),g.has(a)||(g.add(a),a.cleaners.push(g))}function getReactionsForOperation(a){var b=a.target,c=a.key,d=a.type,e=connectionStore.get(b),f=new Set;if('clear'===d)for(var g in e)addReactionsForKey(f,e,g);else addReactionsForKey(f,e,c);if('add'===d||'delete'===d||'clear'===d){var h=Array.isArray(b)?'length':ITERATION_KEY;addReactionsForKey(f,e,h)}return f}function addReactionsForKey(a,b,c){var d=b[c];d&&d.forEach(a.add,a)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=[]}function releaseReactionKeyConnection(a){a.delete(this)}var runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)return b.apply(c,d);releaseReaction(a);try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForOperation(a){runningReaction&&(runningReaction.debugger&&runningReaction.debugger(a),registerReactionForOperation(runningReaction,a))}function queueReactionsForOperation(a){getReactionsForOperation(a).forEach(queueReaction,a)}function queueReaction(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}var IS_REACTION=Symbol('is reaction');function observe(a,b){void 0===b&&(b={});var c=a[IS_REACTION]?a:function b(){return runAsReaction(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[IS_REACTION]=!0,b.lazy||c(),c}function unobserve(a){a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}var proxyToRaw=new WeakMap,rawToProxy=new WeakMap,getPrototypeOf=Object.getPrototypeOf,hasOwnProperty=Object.prototype.hasOwnProperty,instrumentations={has:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForOperation({target:c,key:b,type:'has'}),d.has.apply(c,arguments)},get:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this);return registerRunningReactionForOperation({target:c,key:b,type:'get'}),d.get.apply(c,arguments)},add:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.add.apply(c,arguments);return e||queueReactionsForOperation({target:c,key:b,value:b,type:'add'}),f},set:function a(b,c){var d=proxyToRaw.get(this),e=getPrototypeOf(this),f=e.has.call(d,b),g=e.get.call(d,b),h=e.set.apply(d,arguments);return f?c!==g&&queueReactionsForOperation({target:d,key:b,value:c,oldValue:g,type:'set'}):queueReactionsForOperation({target:d,key:b,value:c,type:'add'}),h},delete:function a(b){var c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,b),f=d.get?d.get.call(c,b):void 0,g=d.delete.apply(c,arguments);return e&&queueReactionsForOperation({target:c,key:b,oldValue:f,type:'delete'}),g},clear:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this),d=0!==b.size,e=b instanceof Map?new Map(b):new Set(b),f=c.clear.apply(b,arguments);return d&&queueReactionsForOperation({target:b,oldTarget:e,type:'clear'}),f},forEach:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.forEach.apply(b,arguments)},keys:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.keys.apply(b,arguments)},values:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.values.apply(b,arguments)},entries:function a(){var b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,type:'iterate'}),c.entries.apply(b,arguments)},get size(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};instrumentations[Symbol.iterator]=function(){var a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)};var collectionHandlers={get:function a(b,c,d){return b=hasOwnProperty.call(instrumentations,c)?instrumentations:b,Reflect.get(b,c,d)}},dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}var hasOwnProperty$1=Object.prototype.hasOwnProperty;function get(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(registerRunningReactionForOperation({target:a,key:b,receiver:c,type:'get'}),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function has(a,b){var c=Reflect.has(a,b);return'symbol'==typeof b?c:(registerRunningReactionForOperation({target:a,key:b,type:'has'}),c)}function ownKeys(a){return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);var e=hasOwnProperty$1.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return hasRunningReaction()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):'symbol'==typeof b||a!==proxyToRaw.get(d)?g:(e?c!==f&&queueReactionsForOperation({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):queueReactionsForOperation({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function deleteProperty(a,b){var c=hasOwnProperty$1.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&queueReactionsForOperation({target:a,key:b,oldValue:d,type:'delete'}),e}var baseHandlers={get:get,has:has,ownKeys:ownKeys,set:set,deleteProperty:deleteProperty};function observable(a){return void 0===a&&(a={}),proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){var b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}export{observe,unobserve,observable,isObservable,raw};
const connectionStore = new WeakMap();
const ITERATION_KEY = Symbol('iteration key');

@@ -8,26 +9,44 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
const reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, { target, key, type }) {
if (type === 'iterate') {
key = ITERATION_KEY;
}
const reactionsForObj = connectionStore.get(target);
let reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
const reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation({ target, key, type }) {
const reactionsForTarget = connectionStore.get(target);
const reactionsForKey = new Set();
if (type === 'clear') {
for (let key in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
const iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
const reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -37,3 +56,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -48,5 +67,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${fn}`);
return fn.apply(context, args);
}

@@ -57,3 +76,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -72,14 +90,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -102,21 +126,9 @@ if (typeof reaction.scheduler === 'function') {

function observe(fn, options = {}) {
if (typeof fn !== 'function') {
throw new TypeError(`The first argument must be a function instead of ${fn}`);
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(`The second argument must be an options object instead of ${options}`);
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
const reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -131,19 +143,3 @@ reaction[IS_REACTION] = true;

function validateOptions({ lazy = false, scheduler }) {
if (typeof lazy !== 'boolean') {
throw new TypeError(`options.lazy must be a boolean or undefined instead of ${lazy}`);
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${scheduler}`);
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(`The first argument must be a reaction instead of ${reaction}`);
}
// do nothing, if the reaction is already unobserved

@@ -165,27 +161,26 @@ if (!reaction.unobserved) {

const ITERATE = Symbol('iterate');
const getPrototypeOf = Object.getPrototypeOf;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const instrumentations = {
has(value) {
const rawContext = proxyToRaw.get(this);
has(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'has' });
return proto.has.apply(target, arguments);
},
get(key) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'get' });
return proto.get.apply(target, arguments);
},
add(value) {
const rawContext = proxyToRaw.get(this);
add(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
const valueChanged = !proto.has.call(rawContext, value);
const result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value: key, type: 'add' });
}

@@ -195,22 +190,24 @@ return result;

set(key, value) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
const valueChanged = proto.get.call(rawContext, key) !== value;
const result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target, key, value, oldValue, type: 'set' });
}
return result;
},
delete(value) {
const rawContext = proxyToRaw.get(this);
delete(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
const valueChanged = proto.has.call(rawContext, value);
const result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -220,9 +217,10 @@ return result;

clear() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadItems = target.size !== 0;
const oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
const valueChanged = rawContext.size !== 0;
const result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
const result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target, oldTarget, type: 'clear' });
}

@@ -232,36 +230,36 @@ return result;

forEach() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
[Symbol.iterator]() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
},
get size() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}

@@ -273,3 +271,3 @@ };

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -299,7 +297,7 @@ }

const ENUMERATE = Symbol('enumerate');
const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
const result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
const result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -309,6 +307,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target, key, receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -323,9 +319,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
const result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target, key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -335,10 +342,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
const hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
const valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
const prevLength = Array.isArray(obj) && obj.length;
const oldValue = target[key];
// execute the set operation before running any reaction
const result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
const lengthChanged = prevLength !== false && prevLength !== obj.length;
const result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -350,29 +355,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target, key, value, receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target,
key,
value,
oldValue,
receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
const hadKey = key in obj;
const hadKey = hasOwnProperty$1.call(target, key);
const oldValue = target[key];
// execute the delete operation before running any reaction
const result = Reflect.deleteProperty(obj, key);
const result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -382,8 +392,5 @@ return result;

var baseHandlers = { get, ownKeys, set, deleteProperty };
var baseHandlers = { get, has, ownKeys, set, deleteProperty };
function observable(obj = {}) {
if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -390,0 +397,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

const connectionStore=new WeakMap;function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForKey(a,b,c){const d=connectionStore.get(a);let e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function iterateReactionsForKey(a,b,c){const d=connectionStore.get(a)[b];d&&Array.from(d).forEach(c)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=void 0}function releaseReactionKeyConnection(a){a.delete(this)}let runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${b}`);releaseReaction(a),a.cleaners=[];try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForKey(a,b){runningReaction&&registerReactionForKey(a,b,runningReaction)}function queueReactionsForKey(a,b){iterateReactionsForKey(a,b,queueReaction)}function queueReaction(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}const IS_REACTION=Symbol('is reaction');function observe(a,b={}){function c(){return runAsReaction(c,a,this,arguments)}if('function'!=typeof a)throw new TypeError(`The first argument must be a function instead of ${a}`);if(a[IS_REACTION])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError(`The second argument must be an options object instead of ${b}`);return validateOptions(b),c.scheduler=b.scheduler,c.runId=0,c[IS_REACTION]=!0,b.lazy||c(),c}function validateOptions({lazy:b=!1,scheduler:a}){if('boolean'!=typeof b)throw new TypeError(`options.lazy must be a boolean or undefined instead of ${b}`);if('object'==typeof a&&null!==a){if('function'!=typeof a.add||'function'!=typeof a.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==a&&'function'!=typeof a)throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${a}`)}function unobserve(a){if('function'!=typeof a||!a[IS_REACTION])throw new TypeError(`The first argument must be a reaction instead of ${a}`);a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}const proxyToRaw=new WeakMap,rawToProxy=new WeakMap,ITERATE=Symbol('iterate'),getPrototypeOf=Object.getPrototypeOf,instrumentations={has(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,a),c.has.apply(b,arguments)},get(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForKey(b,a),c.get.apply(b,arguments)},add(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=!c.has.call(b,a),e=c.add.apply(b,arguments);return d&&(queueReactionsForKey(b,a),queueReactionsForKey(b,ITERATE)),e},set(a,b){const c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.get.call(c,a)!==b,f=d.set.apply(c,arguments);return e&&(queueReactionsForKey(c,a),queueReactionsForKey(c,ITERATE)),f},delete(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.delete.apply(b,arguments);return d&&(queueReactionsForKey(b,a),queueReactionsForKey(b,ITERATE)),e},clear(){const a=proxyToRaw.get(this),b=getPrototypeOf(this),c=0!==a.size,d=b.clear.apply(a,arguments);return c&&queueReactionsForKey(a,ITERATE),d},forEach(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.forEach.apply(a,arguments)},keys(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.keys.apply(a,arguments)},values(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.values.apply(a,arguments)},entries(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),b[Symbol.iterator].apply(a,arguments)},get size(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForKey(a,ITERATE),Reflect.get(b,'size',a)}};var collectionHandlers={get(a,b,c){return a=b in getPrototypeOf(a)?instrumentations:a,Reflect.get(a,b,c)}};const dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}const ENUMERATE=Symbol('enumerate');function get(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=proxyToRaw.get(a)||a,registerRunningReactionForKey(a,b),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function ownKeys(a){return registerRunningReactionForKey(a,ENUMERATE),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);const e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return hasRunningReaction()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):a===proxyToRaw.get(d)?('symbol'!=typeof b&&e&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),h&&queueReactionsForKey(a,'length'),g):g}function deleteProperty(a,b){const c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(queueReactionsForKey(a,b),queueReactionsForKey(a,ENUMERATE)),d}var baseHandlers={get,ownKeys,set,deleteProperty};function observable(a={}){if('object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){const b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}export{observe,unobserve,observable,isObservable,raw};
const connectionStore=new WeakMap,ITERATION_KEY=Symbol('iteration key');function storeObservable(a){connectionStore.set(a,Object.create(null))}function registerReactionForOperation(a,{target:b,key:c,type:d}){'iterate'===d&&(c=ITERATION_KEY);const e=connectionStore.get(b);let f=e[c];f||(e[c]=f=new Set),f.has(a)||(f.add(a),a.cleaners.push(f))}function getReactionsForOperation({target:a,key:b,type:c}){const d=connectionStore.get(a),e=new Set;if('clear'===c)for(let a in d)addReactionsForKey(e,d,a);else addReactionsForKey(e,d,b);if('add'===c||'delete'===c||'clear'===c){const b=Array.isArray(a)?'length':ITERATION_KEY;addReactionsForKey(e,d,b)}return e}function addReactionsForKey(a,b,c){const d=b[c];d&&d.forEach(a.add,a)}function releaseReaction(a){a.cleaners&&a.cleaners.forEach(releaseReactionKeyConnection,a),a.cleaners=[]}function releaseReactionKeyConnection(a){a.delete(this)}let runningReaction;function runAsReaction(a,b,c,d){if(a.unobserved)return b.apply(c,d);releaseReaction(a);try{return runningReaction=a,b.apply(c,d)}finally{runningReaction=void 0}}function registerRunningReactionForOperation(a){runningReaction&&(runningReaction.debugger&&runningReaction.debugger(a),registerReactionForOperation(runningReaction,a))}function queueReactionsForOperation(a){getReactionsForOperation(a).forEach(queueReaction,a)}function queueReaction(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function hasRunningReaction(){return runningReaction!==void 0}const IS_REACTION=Symbol('is reaction');function observe(a,b={}){const c=a[IS_REACTION]?a:function b(){return runAsReaction(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[IS_REACTION]=!0,b.lazy||c(),c}function unobserve(a){a.unobserved||(a.unobserved=!0,releaseReaction(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}const proxyToRaw=new WeakMap,rawToProxy=new WeakMap,getPrototypeOf=Object.getPrototypeOf,hasOwnProperty=Object.prototype.hasOwnProperty,instrumentations={has(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,key:a,type:'has'}),c.has.apply(b,arguments)},get(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this);return registerRunningReactionForOperation({target:b,key:a,type:'get'}),c.get.apply(b,arguments)},add(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.add.apply(b,arguments);return d||queueReactionsForOperation({target:b,key:a,value:a,type:'add'}),e},set(a,b){const c=proxyToRaw.get(this),d=getPrototypeOf(this),e=d.has.call(c,a),f=d.get.call(c,a),g=d.set.apply(c,arguments);return e?b!==f&&queueReactionsForOperation({target:c,key:a,value:b,oldValue:f,type:'set'}):queueReactionsForOperation({target:c,key:a,value:b,type:'add'}),g},delete(a){const b=proxyToRaw.get(this),c=getPrototypeOf(this),d=c.has.call(b,a),e=c.get?c.get.call(b,a):void 0,f=c.delete.apply(b,arguments);return d&&queueReactionsForOperation({target:b,key:a,oldValue:e,type:'delete'}),f},clear(){const a=proxyToRaw.get(this),b=getPrototypeOf(this),c=0!==a.size,d=a instanceof Map?new Map(a):new Set(a),e=b.clear.apply(a,arguments);return c&&queueReactionsForOperation({target:a,oldTarget:d,type:'clear'}),e},forEach(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.forEach.apply(a,arguments)},keys(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.keys.apply(a,arguments)},values(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.values.apply(a,arguments)},entries(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)},get size(){const a=proxyToRaw.get(this),b=getPrototypeOf(this);return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};var collectionHandlers={get(a,b,c){return a=hasOwnProperty.call(instrumentations,b)?instrumentations:a,Reflect.get(a,b,c)}};const dontInstrument=new Set([Date,RegExp]),handlers=new Map([[Map,collectionHandlers],[Set,collectionHandlers],[WeakMap,collectionHandlers],[WeakSet,collectionHandlers]]);function shouldInstrument(a){return'function'==typeof Node&&a instanceof Node?!1:!dontInstrument.has(a.constructor)}function getHandlers(a){return handlers.get(a.constructor)}const hasOwnProperty$1=Object.prototype.hasOwnProperty;function get(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(registerRunningReactionForOperation({target:a,key:b,receiver:c,type:'get'}),hasRunningReaction()&&'object'==typeof d&&null!==d?observable(d):rawToProxy.get(d)||d)}function has(a,b){const c=Reflect.has(a,b);return'symbol'==typeof b?c:(registerRunningReactionForOperation({target:a,key:b,type:'has'}),c)}function ownKeys(a){return registerRunningReactionForOperation({target:a,type:'iterate'}),Reflect.ownKeys(a)}function set(a,b,c,d){'object'==typeof c&&null!==c&&(c=proxyToRaw.get(c)||c);const e=hasOwnProperty$1.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return hasRunningReaction()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):'symbol'==typeof b||a!==proxyToRaw.get(d)?g:(e?c!==f&&queueReactionsForOperation({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):queueReactionsForOperation({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function deleteProperty(a,b){const c=hasOwnProperty$1.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&queueReactionsForOperation({target:a,key:b,oldValue:d,type:'delete'}),e}var baseHandlers={get,has,ownKeys,set,deleteProperty};function observable(a={}){return proxyToRaw.has(a)||!shouldInstrument(a)?a:rawToProxy.get(a)||createObservable(a)}function createObservable(a){const b=getHandlers(a)||baseHandlers,c=new Proxy(a,b);return rawToProxy.set(a,c),proxyToRaw.set(c,a),storeObservable(a),c}function isObservable(a){return proxyToRaw.has(a)}function raw(a){return proxyToRaw.get(a)||a}export{observe,unobserve,observable,isObservable,raw};

@@ -8,2 +8,3 @@ (function (global, factory) {

var connectionStore = new WeakMap();
var ITERATION_KEY = Symbol('iteration key');

@@ -15,26 +16,52 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
var reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
if (type === 'iterate') {
key = ITERATION_KEY;
}
var reactionsForObj = connectionStore.get(target);
var reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
var reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation(ref) {
var target = ref.target;
var key = ref.key;
var type = ref.type;
var reactionsForTarget = connectionStore.get(target);
var reactionsForKey = new Set();
if (type === 'clear') {
for (var key$1 in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key$1);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
var iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
var reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -44,3 +71,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -55,5 +82,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(("Unobserved reactions can not be executed. You tried to run a reaction for " + fn));
return fn.apply(context, args);
}

@@ -64,3 +91,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -79,14 +105,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -111,21 +143,9 @@ if (typeof reaction.scheduler === 'function') {

if (typeof fn !== 'function') {
throw new TypeError(("The first argument must be a function instead of " + fn));
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(("The second argument must be an options object instead of " + options));
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
var reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -140,22 +160,3 @@ reaction[IS_REACTION] = true;

function validateOptions(ref) {
var lazy = ref.lazy; if ( lazy === void 0 ) lazy = false;
var scheduler = ref.scheduler;
if (typeof lazy !== 'boolean') {
throw new TypeError(("options.lazy must be a boolean or undefined instead of " + lazy));
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(("options.scheduler must be a function, an object or undefined instead of " + scheduler));
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(("The first argument must be a reaction instead of " + reaction));
}
// do nothing, if the reaction is already unobserved

@@ -177,27 +178,26 @@ if (!reaction.unobserved) {

var ITERATE = Symbol('iterate');
var getPrototypeOf = Object.getPrototypeOf;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var instrumentations = {
has: function has(value) {
var rawContext = proxyToRaw.get(this);
has: function has(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return proto.has.apply(target, arguments);
},
get: function get(key) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, key: key, type: 'get' });
return proto.get.apply(target, arguments);
},
add: function add(value) {
var rawContext = proxyToRaw.get(this);
add: function add(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
var valueChanged = !proto.has.call(rawContext, value);
var result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: key, type: 'add' });
}

@@ -207,22 +207,24 @@ return result;

set: function set(key, value) {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
var valueChanged = proto.get.call(rawContext, key) !== value;
var result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target: target, key: key, value: value, oldValue: oldValue, type: 'set' });
}
return result;
},
delete: function delete$1(value) {
var rawContext = proxyToRaw.get(this);
delete: function delete$1(key) {
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadKey = proto.has.call(target, key);
var oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
var valueChanged = proto.has.call(rawContext, value);
var result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
var result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -232,9 +234,10 @@ return result;

clear: function clear() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
var hadItems = target.size !== 0;
var oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
var valueChanged = rawContext.size !== 0;
var result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
var result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target: target, oldTarget: oldTarget, type: 'clear' });
}

@@ -244,37 +247,37 @@ return result;

forEach: function forEach() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys: function keys() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values: function values() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries: function entries() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
get size() {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}
};
instrumentations[Symbol.iterator] = function () {
var rawContext = proxyToRaw.get(this);
var target = proxyToRaw.get(this);
var proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
};

@@ -285,3 +288,3 @@

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -311,7 +314,7 @@ }

var ENUMERATE = Symbol('enumerate');
var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
var result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
var result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -321,6 +324,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target: target, key: key, receiver: receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -335,9 +336,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
var result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target: target, key: key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target: target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -347,10 +359,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
var hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
var valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
var prevLength = Array.isArray(obj) && obj.length;
var oldValue = target[key];
// execute the set operation before running any reaction
var result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
var lengthChanged = prevLength !== false && prevLength !== obj.length;
var result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -362,29 +372,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target: target, key: key, value: value, receiver: receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target: target,
key: key,
value: value,
oldValue: oldValue,
receiver: receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
var hadKey = key in obj;
var hadKey = hasOwnProperty$1.call(target, key);
var oldValue = target[key];
// execute the delete operation before running any reaction
var result = Reflect.deleteProperty(obj, key);
var result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target: target, key: key, oldValue: oldValue, type: 'delete' });
}

@@ -394,3 +409,3 @@ return result;

var baseHandlers = { get: get, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };
var baseHandlers = { get: get, has: has, ownKeys: ownKeys, set: set, deleteProperty: deleteProperty };

@@ -400,5 +415,2 @@ function observable(obj) {

if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -405,0 +417,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?b(exports):'function'==typeof define&&define.amd?define(['exports'],b):b(a.observer={})})(this,function(a){'use strict';function b(a){z.set(a,Object.create(null))}function c(a,b,c){var d=z.get(a),e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function d(a,b,c){var d=z.get(a)[b];d&&Array.from(d).forEach(c)}function e(a){a.cleaners&&a.cleaners.forEach(f,a),a.cleaners=void 0}function f(a){a.delete(this)}function g(a,b,c,d){if(a.unobserved)throw new Error('Unobserved reactions can not be executed. You tried to run a reaction for '+b);e(a),a.cleaners=[];try{return y=a,b.apply(c,d)}finally{y=void 0}}function h(a,b){y&&c(a,b,y)}function i(a,b){d(a,b,j)}function j(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function k(){return y!==void 0}function l(a,b){function c(){return g(c,a,this,arguments)}if(void 0===b&&(b={}),'function'!=typeof a)throw new TypeError('The first argument must be a function instead of '+a);if(a[A])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError('The second argument must be an options object instead of '+b);return m(b),c.scheduler=b.scheduler,c.runId=0,c[A]=!0,b.lazy||c(),c}function m(a){var b=a.lazy;void 0===b&&(b=!1);var c=a.scheduler;if('boolean'!=typeof b)throw new TypeError('options.lazy must be a boolean or undefined instead of '+b);if('object'==typeof c&&null!==c){if('function'!=typeof c.add||'function'!=typeof c.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==c&&'function'!=typeof c)throw new TypeError('options.scheduler must be a function, an object or undefined instead of '+c)}function n(a){if('function'!=typeof a||!a[A])throw new TypeError('The first argument must be a reaction instead of '+a);a.unobserved||(a.unobserved=!0,e(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}function o(a){return'function'==typeof Node&&a instanceof Node?!1:!H.has(a.constructor)}function p(a){return I.get(a.constructor)}function q(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=B.get(a)||a,h(a,b),k()&&'object'==typeof d&&null!==d?u(d):C.get(d)||d)}function r(a){return h(a,J),Reflect.ownKeys(a)}function s(a,b,c,d){'object'==typeof c&&null!==c&&(c=B.get(c)||c);var e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return k()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):a===B.get(d)?('symbol'!=typeof b&&e&&(i(a,b),i(a,J)),h&&i(a,'length'),g):g}function t(a,b){var c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(i(a,b),i(a,J)),d}function u(a){if(void 0===a&&(a={}),'object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return B.has(a)||!o(a)?a:C.get(a)||v(a)}function v(a){var c=p(a)||K,d=new Proxy(a,c);return C.set(a,d),B.set(d,a),b(a),d}function w(a){return B.has(a)}function x(a){return B.get(a)||a}var y,z=new WeakMap,A=Symbol('is reaction'),B=new WeakMap,C=new WeakMap,D=Symbol('iterate'),E=Object.getPrototypeOf,F={has:function a(b){var c=B.get(this),d=E(this);return h(c,b),d.has.apply(c,arguments)},get:function a(b){var c=B.get(this),d=E(this);return h(c,b),d.get.apply(c,arguments)},add:function a(b){var c=B.get(this),d=E(this),e=!d.has.call(c,b),f=d.add.apply(c,arguments);return e&&(i(c,b),i(c,D)),f},set:function a(b,c){var d=B.get(this),e=E(this),f=e.get.call(d,b)!==c,g=e.set.apply(d,arguments);return f&&(i(d,b),i(d,D)),g},delete:function a(b){var c=B.get(this),d=E(this),e=d.has.call(c,b),f=d.delete.apply(c,arguments);return e&&(i(c,b),i(c,D)),f},clear:function a(){var b=B.get(this),c=E(this),d=0!==b.size,e=c.clear.apply(b,arguments);return d&&i(b,D),e},forEach:function a(){var b=B.get(this),c=E(this);return h(b,D),c.forEach.apply(b,arguments)},keys:function a(){var b=B.get(this),c=E(this);return h(b,D),c.keys.apply(b,arguments)},values:function a(){var b=B.get(this),c=E(this);return h(b,D),c.values.apply(b,arguments)},entries:function a(){var b=B.get(this),c=E(this);return h(b,D),c.entries.apply(b,arguments)},get size(){var a=B.get(this),b=E(this);return h(a,D),Reflect.get(b,'size',a)}};F[Symbol.iterator]=function(){var a=B.get(this),b=E(this);return h(a,D),b[Symbol.iterator].apply(a,arguments)};var G={get:function a(b,c,d){return b=c in E(b)?F:b,Reflect.get(b,c,d)}},H=new Set([Date,RegExp]),I=new Map([[Map,G],[Set,G],[WeakMap,G],[WeakSet,G]]),J=Symbol('enumerate'),K={get:q,ownKeys:r,set:s,deleteProperty:t};a.observe=l,a.unobserve=n,a.observable=u,a.isObservable=w,a.raw=x,Object.defineProperty(a,'__esModule',{value:!0})});
(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?b(exports):'function'==typeof define&&define.amd?define(['exports'],b):b(a.observer={})})(this,function(a){'use strict';function b(a){A.set(a,Object.create(null))}function c(a,b){var c=b.target,d=b.key,e=b.type;'iterate'===e&&(d=B);var f=A.get(c),g=f[d];g||(f[d]=g=new Set),g.has(a)||(g.add(a),a.cleaners.push(g))}function d(a){var b=a.target,c=a.key,d=a.type,f=A.get(b),g=new Set;if('clear'===d)for(var h in f)e(g,f,h);else e(g,f,c);if('add'===d||'delete'===d||'clear'===d){var i=Array.isArray(b)?'length':B;e(g,f,i)}return g}function e(a,b,c){var d=b[c];d&&d.forEach(a.add,a)}function f(a){a.cleaners&&a.cleaners.forEach(g,a),a.cleaners=[]}function g(a){a.delete(this)}function h(a,b,c,d){if(a.unobserved)return b.apply(c,d);f(a);try{return z=a,b.apply(c,d)}finally{z=void 0}}function i(a){z&&(z.debugger&&z.debugger(a),c(z,a))}function j(a){d(a).forEach(k,a)}function k(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function l(){return z!==void 0}function m(a,b){void 0===b&&(b={});var c=a[C]?a:function b(){return h(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[C]=!0,b.lazy||c(),c}function n(a){a.unobserved||(a.unobserved=!0,f(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}function o(a){return'function'==typeof Node&&a instanceof Node?!1:!J.has(a.constructor)}function p(a){return K.get(a.constructor)}function q(a,b,c){var d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(i({target:a,key:b,receiver:c,type:'get'}),l()&&'object'==typeof d&&null!==d?v(d):E.get(d)||d)}function r(a,b){var c=Reflect.has(a,b);return'symbol'==typeof b?c:(i({target:a,key:b,type:'has'}),c)}function s(a){return i({target:a,type:'iterate'}),Reflect.ownKeys(a)}function t(a,b,c,d){'object'==typeof c&&null!==c&&(c=D.get(c)||c);var e=L.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return l()?(console.error('Mutating observables in reactions is forbidden. You set '+b+' to '+c+'.'),g):'symbol'==typeof b||a!==D.get(d)?g:(e?c!==f&&j({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):j({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function u(a,b){var c=L.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&j({target:a,key:b,oldValue:d,type:'delete'}),e}function v(a){return void 0===a&&(a={}),D.has(a)||!o(a)?a:E.get(a)||w(a)}function w(a){var c=p(a)||M,d=new Proxy(a,c);return E.set(a,d),D.set(d,a),b(a),d}function x(a){return D.has(a)}function y(a){return D.get(a)||a}var z,A=new WeakMap,B=Symbol('iteration key'),C=Symbol('is reaction'),D=new WeakMap,E=new WeakMap,F=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty,H={has:function a(b){var c=D.get(this),d=F(this);return i({target:c,key:b,type:'has'}),d.has.apply(c,arguments)},get:function a(b){var c=D.get(this),d=F(this);return i({target:c,key:b,type:'get'}),d.get.apply(c,arguments)},add:function a(b){var c=D.get(this),d=F(this),e=d.has.call(c,b),f=d.add.apply(c,arguments);return e||j({target:c,key:b,value:b,type:'add'}),f},set:function a(b,c){var d=D.get(this),e=F(this),f=e.has.call(d,b),g=e.get.call(d,b),h=e.set.apply(d,arguments);return f?c!==g&&j({target:d,key:b,value:c,oldValue:g,type:'set'}):j({target:d,key:b,value:c,type:'add'}),h},delete:function a(b){var c=D.get(this),d=F(this),e=d.has.call(c,b),f=d.get?d.get.call(c,b):void 0,g=d.delete.apply(c,arguments);return e&&j({target:c,key:b,oldValue:f,type:'delete'}),g},clear:function a(){var b=D.get(this),c=F(this),d=0!==b.size,e=b instanceof Map?new Map(b):new Set(b),f=c.clear.apply(b,arguments);return d&&j({target:b,oldTarget:e,type:'clear'}),f},forEach:function a(){var b=D.get(this),c=F(this);return i({target:b,type:'iterate'}),c.forEach.apply(b,arguments)},keys:function a(){var b=D.get(this),c=F(this);return i({target:b,type:'iterate'}),c.keys.apply(b,arguments)},values:function a(){var b=D.get(this),c=F(this);return i({target:b,type:'iterate'}),c.values.apply(b,arguments)},entries:function a(){var b=D.get(this),c=F(this);return i({target:b,type:'iterate'}),c.entries.apply(b,arguments)},get size(){var a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};H[Symbol.iterator]=function(){var a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)};var I={get:function a(b,c,d){return b=G.call(H,c)?H:b,Reflect.get(b,c,d)}},J=new Set([Date,RegExp]),K=new Map([[Map,I],[Set,I],[WeakMap,I],[WeakSet,I]]),L=Object.prototype.hasOwnProperty,M={get:q,has:r,ownKeys:s,set:t,deleteProperty:u};a.observe=m,a.unobserve=n,a.observable=v,a.isObservable=x,a.raw=y,Object.defineProperty(a,'__esModule',{value:!0})});

@@ -8,2 +8,3 @@ (function (global, factory) {

const connectionStore = new WeakMap();
const ITERATION_KEY = Symbol('iteration key');

@@ -15,26 +16,44 @@ function storeObservable(obj) {

function registerReactionForKey(obj, key, reaction) {
const reactionsForObj = connectionStore.get(obj);
function registerReactionForOperation(reaction, { target, key, type }) {
if (type === 'iterate') {
key = ITERATION_KEY;
}
const reactionsForObj = connectionStore.get(target);
let reactionsForKey = reactionsForObj[key];
if (!reactionsForKey) {
reactionsForObj[key] = reactionsForKey = new Set();
// save the fact that the key is used by the reaction during its current run
}
// save the fact that the key is used by the reaction during its current run
if (!reactionsForKey.has(reaction)) {
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
} else if (!reactionsForKey.has(reaction)) {
// save the fact that the key is used by the reaction during its current run
reactionsForKey.add(reaction);
reaction.cleaners.push(reactionsForKey);
}
}
function iterateReactionsForKey(obj, key, reactionHandler) {
const reactionsForKey = connectionStore.get(obj)[key];
if (reactionsForKey) {
// create a static copy of the reactions, before iterating them
// to avoid infinite (iterate items: remove -> readd) loops
Array.from(reactionsForKey).forEach(reactionHandler);
function getReactionsForOperation({ target, key, type }) {
const reactionsForTarget = connectionStore.get(target);
const reactionsForKey = new Set();
if (type === 'clear') {
for (let key in reactionsForTarget) {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
} else {
addReactionsForKey(reactionsForKey, reactionsForTarget, key);
}
if (type === 'add' || type === 'delete' || type === 'clear') {
const iterationKey = Array.isArray(target) ? 'length' : ITERATION_KEY;
addReactionsForKey(reactionsForKey, reactionsForTarget, iterationKey);
}
return reactionsForKey;
}
function addReactionsForKey(reactionsForKey, reactionsForTarget, key) {
const reactions = reactionsForTarget[key];
reactions && reactions.forEach(reactionsForKey.add, reactionsForKey);
}
function releaseReaction(reaction) {

@@ -44,3 +63,3 @@ if (reaction.cleaners) {

}
reaction.cleaners = undefined;
reaction.cleaners = [];
}

@@ -55,5 +74,5 @@

function runAsReaction(reaction, fn, context, args) {
// throw an error if the reaction is unobserved
// do not build reactive relations, if the reaction is unobserved
if (reaction.unobserved) {
throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${fn}`);
return fn.apply(context, args);
}

@@ -64,3 +83,2 @@

releaseReaction(reaction);
reaction.cleaners = [];

@@ -79,14 +97,20 @@ try {

// register the currently running reaction to be queued again on obj.key mutations
function registerRunningReactionForKey(obj, key) {
function registerRunningReactionForOperation(operation) {
if (runningReaction) {
registerReactionForKey(obj, key, runningReaction);
if (runningReaction.debugger) {
runningReaction.debugger(operation);
}
registerReactionForOperation(runningReaction, operation);
}
}
function queueReactionsForKey(obj, key) {
function queueReactionsForOperation(operation) {
// iterate and queue every reaction, which is triggered by obj.key mutation
iterateReactionsForKey(obj, key, queueReaction);
getReactionsForOperation(operation).forEach(queueReaction, operation);
}
function queueReaction(reaction) {
if (reaction.debugger) {
reaction.debugger(this);
}
// queue the reaction for later execution or run it immediately

@@ -109,21 +133,9 @@ if (typeof reaction.scheduler === 'function') {

function observe(fn, options = {}) {
if (typeof fn !== 'function') {
throw new TypeError(`The first argument must be a function instead of ${fn}`);
}
if (fn[IS_REACTION]) {
throw new TypeError('The first argument must not be an already observed reaction');
}
if (typeof options !== 'object' || options === null) {
throw new TypeError(`The second argument must be an options object instead of ${options}`);
}
validateOptions(options);
// create a reaction from the passed function
function reaction() {
// wrap the passed function in a reaction, if it is not already one
const reaction = fn[IS_REACTION] ? fn : function reaction() {
return runAsReaction(reaction, fn, this, arguments);
}
// save the scheduler on the reaction
};
// save the scheduler and debugger on the reaction
reaction.scheduler = options.scheduler;
// runId will serve as a unique (incremental) id, which identifies the reaction's last run
reaction.runId = 0;
reaction.debugger = options.debugger;
// save the fact that this is a reaction

@@ -138,19 +150,3 @@ reaction[IS_REACTION] = true;

function validateOptions({ lazy = false, scheduler }) {
if (typeof lazy !== 'boolean') {
throw new TypeError(`options.lazy must be a boolean or undefined instead of ${lazy}`);
}
if (typeof scheduler === 'object' && scheduler !== null) {
if (typeof scheduler.add !== 'function' || typeof scheduler.delete !== 'function') {
throw new TypeError('options.scheduler object must have an add and delete method');
}
} else if (scheduler !== undefined && typeof scheduler !== 'function') {
throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${scheduler}`);
}
}
function unobserve(reaction) {
if (typeof reaction !== 'function' || !reaction[IS_REACTION]) {
throw new TypeError(`The first argument must be a reaction instead of ${reaction}`);
}
// do nothing, if the reaction is already unobserved

@@ -172,27 +168,26 @@ if (!reaction.unobserved) {

const ITERATE = Symbol('iterate');
const getPrototypeOf = Object.getPrototypeOf;
const hasOwnProperty = Object.prototype.hasOwnProperty;
const instrumentations = {
has(value) {
const rawContext = proxyToRaw.get(this);
has(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, value);
return proto.has.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'has' });
return proto.has.apply(target, arguments);
},
get(key) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, key);
return proto.get.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, key, type: 'get' });
return proto.get.apply(target, arguments);
},
add(value) {
const rawContext = proxyToRaw.get(this);
add(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
// forward the operation before queueing reactions
const valueChanged = !proto.has.call(rawContext, value);
const result = proto.add.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.add.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value: key, type: 'add' });
}

@@ -202,22 +197,24 @@ return result;

set(key, value) {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get.call(target, key);
// forward the operation before queueing reactions
const valueChanged = proto.get.call(rawContext, key) !== value;
const result = proto.set.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, key);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.set.apply(target, arguments);
if (!hadKey) {
queueReactionsForOperation({ target, key, value, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({ target, key, value, oldValue, type: 'set' });
}
return result;
},
delete(value) {
const rawContext = proxyToRaw.get(this);
delete(key) {
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadKey = proto.has.call(target, key);
const oldValue = proto.get ? proto.get.call(target, key) : undefined;
// forward the operation before queueing reactions
const valueChanged = proto.has.call(rawContext, value);
const result = proto.delete.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, value);
queueReactionsForKey(rawContext, ITERATE);
const result = proto.delete.apply(target, arguments);
if (hadKey) {
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -227,9 +224,10 @@ return result;

clear() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
const hadItems = target.size !== 0;
const oldTarget = target instanceof Map ? new Map(target) : new Set(target);
// forward the operation before queueing reactions
const valueChanged = rawContext.size !== 0;
const result = proto.clear.apply(rawContext, arguments);
if (valueChanged) {
queueReactionsForKey(rawContext, ITERATE);
const result = proto.clear.apply(target, arguments);
if (hadItems) {
queueReactionsForOperation({ target, oldTarget, type: 'clear' });
}

@@ -239,36 +237,36 @@ return result;

forEach() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.forEach.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.forEach.apply(target, arguments);
},
keys() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.keys.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.keys.apply(target, arguments);
},
values() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.values.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.values.apply(target, arguments);
},
entries() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto.entries.apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto.entries.apply(target, arguments);
},
[Symbol.iterator]() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return proto[Symbol.iterator].apply(rawContext, arguments);
registerRunningReactionForOperation({ target, type: 'iterate' });
return proto[Symbol.iterator].apply(target, arguments);
},
get size() {
const rawContext = proxyToRaw.get(this);
const target = proxyToRaw.get(this);
const proto = getPrototypeOf(this);
registerRunningReactionForKey(rawContext, ITERATE);
return Reflect.get(proto, 'size', rawContext);
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.get(proto, 'size', target);
}

@@ -280,3 +278,3 @@ };

// instrument methods and property accessors to be reactive
target = key in getPrototypeOf(target) ? instrumentations : target;
target = hasOwnProperty.call(instrumentations, key) ? instrumentations : target;
return Reflect.get(target, key, receiver);

@@ -306,7 +304,7 @@ }

const ENUMERATE = Symbol('enumerate');
const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// intercept get operations on observables to know which reaction uses their properties
function get(obj, key, receiver) {
const result = Reflect.get(obj, key, receiver);
function get(target, key, receiver) {
const result = Reflect.get(target, key, receiver);
// do not register (observable.prop -> reaction) pairs for these cases

@@ -316,6 +314,4 @@ if (typeof key === 'symbol' || typeof result === 'function') {

}
// make sure to use the raw object here, obj might be a Proxy because of inheritance
obj = proxyToRaw.get(obj) || obj;
// register and save (observable.prop -> runningReaction)
registerRunningReactionForKey(obj, key);
registerRunningReactionForOperation({ target, key, receiver, type: 'get' });
// if we are inside a reaction and observable.prop is an object wrap it in an observable too

@@ -330,9 +326,20 @@ // this is needed to intercept property access on that object too (dynamic observable tree)

function ownKeys(obj) {
registerRunningReactionForKey(obj, ENUMERATE);
return Reflect.ownKeys(obj);
function has(target, key) {
const result = Reflect.has(target, key);
// do not register (observable.prop -> reaction) pairs for these cases
if (typeof key === 'symbol') {
return result;
}
// register and save (observable.prop -> runningReaction)
registerRunningReactionForOperation({ target, key, type: 'has' });
return result;
}
function ownKeys(target) {
registerRunningReactionForOperation({ target, type: 'iterate' });
return Reflect.ownKeys(target);
}
// intercept set operations on observables to know when to trigger reactions
function set(obj, key, value, receiver) {
function set(target, key, value, receiver) {
// make sure to do not pollute the raw object with observables

@@ -342,10 +349,8 @@ if (typeof value === 'object' && value !== null) {

}
// save if the object had a descriptor for this key
const hadKey = hasOwnProperty$1.call(target, key);
// save if the value changed because of this set operation
const valueChanged = value !== obj[key];
// length is lazy, it can change without an explicit length set operation
const prevLength = Array.isArray(obj) && obj.length;
const oldValue = target[key];
// execute the set operation before running any reaction
const result = Reflect.set(obj, key, value, receiver);
// check if the length changed implicitly, because of out of bound set operations
const lengthChanged = prevLength !== false && prevLength !== obj.length;
const result = Reflect.set(target, key, value, receiver);
// emit a warning and do not queue anything when another reaction is queued

@@ -357,29 +362,34 @@ // from an already running reaction

}
// if the target of the operation is not the raw receiver return
// do not queue reactions if it is a symbol keyed property
// or the target of the operation is not the raw receiver
// (possible because of prototypal inheritance)
if (obj !== proxyToRaw.get(receiver)) {
if (typeof key === 'symbol' || target !== proxyToRaw.get(receiver)) {
return result;
}
// do not queue reactions if it is a symbol keyed property
// or the set operation resulted in no value change
if (typeof key !== 'symbol' && valueChanged) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
// queue a reaction if it's a new property or its value changed
if (!hadKey) {
queueReactionsForOperation({ target, key, value, receiver, type: 'add' });
} else if (value !== oldValue) {
queueReactionsForOperation({
target,
key,
value,
oldValue,
receiver,
type: 'set'
});
}
// queue length reactions in case the length changed
if (lengthChanged) {
queueReactionsForKey(obj, 'length');
}
return result;
}
function deleteProperty(obj, key) {
function deleteProperty(target, key) {
// save if the object had the key
const hadKey = key in obj;
const hadKey = hasOwnProperty$1.call(target, key);
const oldValue = target[key];
// execute the delete operation before running any reaction
const result = Reflect.deleteProperty(obj, key);
const result = Reflect.deleteProperty(target, key);
// only queue reactions for non symbol keyed property delete which resulted in an actual change
if (typeof key !== 'symbol' && hadKey) {
queueReactionsForKey(obj, key);
queueReactionsForKey(obj, ENUMERATE);
queueReactionsForOperation({ target, key, oldValue, type: 'delete' });
}

@@ -389,8 +399,5 @@ return result;

var baseHandlers = { get, ownKeys, set, deleteProperty };
var baseHandlers = { get, has, ownKeys, set, deleteProperty };
function observable(obj = {}) {
if (typeof obj !== 'object') {
throw new TypeError('Observable first argument must be an object or undefined');
}
// if it is already an observable or it should not be wrapped, return it

@@ -397,0 +404,0 @@ if (proxyToRaw.has(obj) || !shouldInstrument(obj)) {

@@ -1,1 +0,1 @@

(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?b(exports):'function'==typeof define&&define.amd?define(['exports'],b):b(a.observer={})})(this,function(a){'use strict';function b(a){y.set(a,Object.create(null))}function c(a,b,c){const d=y.get(a);let e=d[b];e?!e.has(c)&&(e.add(c),c.cleaners.push(e)):(d[b]=e=new Set,e.add(c),c.cleaners.push(e))}function d(a,b,c){const d=y.get(a)[b];d&&Array.from(d).forEach(c)}function e(a){a.cleaners&&a.cleaners.forEach(f,a),a.cleaners=void 0}function f(a){a.delete(this)}function g(a,b,c,d){if(a.unobserved)throw new Error(`Unobserved reactions can not be executed. You tried to run a reaction for ${b}`);e(a),a.cleaners=[];try{return z=a,b.apply(c,d)}finally{z=void 0}}function h(a,b){z&&c(a,b,z)}function i(a,b){d(a,b,j)}function j(a){'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function k(){return z!==void 0}function l(a,b={}){function c(){return g(c,a,this,arguments)}if('function'!=typeof a)throw new TypeError(`The first argument must be a function instead of ${a}`);if(a[A])throw new TypeError('The first argument must not be an already observed reaction');if('object'!=typeof b||null===b)throw new TypeError(`The second argument must be an options object instead of ${b}`);return m(b),c.scheduler=b.scheduler,c.runId=0,c[A]=!0,b.lazy||c(),c}function m({lazy:b=!1,scheduler:a}){if('boolean'!=typeof b)throw new TypeError(`options.lazy must be a boolean or undefined instead of ${b}`);if('object'==typeof a&&null!==a){if('function'!=typeof a.add||'function'!=typeof a.delete)throw new TypeError('options.scheduler object must have an add and delete method');}else if(void 0!==a&&'function'!=typeof a)throw new TypeError(`options.scheduler must be a function, an object or undefined instead of ${a}`)}function n(a){if('function'!=typeof a||!a[A])throw new TypeError(`The first argument must be a reaction instead of ${a}`);a.unobserved||(a.unobserved=!0,e(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}function o(a){return'function'==typeof Node&&a instanceof Node?!1:!H.has(a.constructor)}function p(a){return I.get(a.constructor)}function q(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(a=B.get(a)||a,h(a,b),k()&&'object'==typeof d&&null!==d?u(d):C.get(d)||d)}function r(a){return h(a,J),Reflect.ownKeys(a)}function s(a,b,c,d){'object'==typeof c&&null!==c&&(c=B.get(c)||c);const e=c!==a[b],f=Array.isArray(a)&&a.length,g=Reflect.set(a,b,c,d),h=!1!==f&&f!==a.length;return k()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):a===B.get(d)?('symbol'!=typeof b&&e&&(i(a,b),i(a,J)),h&&i(a,'length'),g):g}function t(a,b){const c=b in a,d=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&(i(a,b),i(a,J)),d}function u(a={}){if('object'!=typeof a)throw new TypeError('Observable first argument must be an object or undefined');return B.has(a)||!o(a)?a:C.get(a)||v(a)}function v(a){const c=p(a)||K,d=new Proxy(a,c);return C.set(a,d),B.set(d,a),b(a),d}function w(a){return B.has(a)}function x(a){return B.get(a)||a}const y=new WeakMap;let z;const A=Symbol('is reaction'),B=new WeakMap,C=new WeakMap,D=Symbol('iterate'),E=Object.getPrototypeOf,F={has(a){const b=B.get(this),c=E(this);return h(b,a),c.has.apply(b,arguments)},get(a){const b=B.get(this),c=E(this);return h(b,a),c.get.apply(b,arguments)},add(a){const b=B.get(this),c=E(this),d=!c.has.call(b,a),e=c.add.apply(b,arguments);return d&&(i(b,a),i(b,D)),e},set(a,b){const c=B.get(this),d=E(this),e=d.get.call(c,a)!==b,f=d.set.apply(c,arguments);return e&&(i(c,a),i(c,D)),f},delete(a){const b=B.get(this),c=E(this),d=c.has.call(b,a),e=c.delete.apply(b,arguments);return d&&(i(b,a),i(b,D)),e},clear(){const a=B.get(this),b=E(this),c=0!==a.size,d=b.clear.apply(a,arguments);return c&&i(a,D),d},forEach(){const a=B.get(this),b=E(this);return h(a,D),b.forEach.apply(a,arguments)},keys(){const a=B.get(this),b=E(this);return h(a,D),b.keys.apply(a,arguments)},values(){const a=B.get(this),b=E(this);return h(a,D),b.values.apply(a,arguments)},entries(){const a=B.get(this),b=E(this);return h(a,D),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=B.get(this),b=E(this);return h(a,D),b[Symbol.iterator].apply(a,arguments)},get size(){const a=B.get(this),b=E(this);return h(a,D),Reflect.get(b,'size',a)}};var G={get(a,b,c){return a=b in E(a)?F:a,Reflect.get(a,b,c)}};const H=new Set([Date,RegExp]),I=new Map([[Map,G],[Set,G],[WeakMap,G],[WeakSet,G]]),J=Symbol('enumerate');var K={get:q,ownKeys:r,set:s,deleteProperty:t};a.observe=l,a.unobserve=n,a.observable=u,a.isObservable=w,a.raw=x,Object.defineProperty(a,'__esModule',{value:!0})});
(function(a,b){'object'==typeof exports&&'undefined'!=typeof module?b(exports):'function'==typeof define&&define.amd?define(['exports'],b):b(a.observer={})})(this,function(a){'use strict';function b(a){z.set(a,Object.create(null))}function c(a,{target:b,key:c,type:d}){'iterate'===d&&(c=A);const e=z.get(b);let f=e[c];f||(e[c]=f=new Set),f.has(a)||(f.add(a),a.cleaners.push(f))}function d({target:a,key:b,type:c}){const d=z.get(a),f=new Set;if('clear'===c)for(let a in d)e(f,d,a);else e(f,d,b);if('add'===c||'delete'===c||'clear'===c){const b=Array.isArray(a)?'length':A;e(f,d,b)}return f}function e(a,b,c){const d=b[c];d&&d.forEach(a.add,a)}function f(a){a.cleaners&&a.cleaners.forEach(g,a),a.cleaners=[]}function g(a){a.delete(this)}function h(a,b,c,d){if(a.unobserved)return b.apply(c,d);f(a);try{return B=a,b.apply(c,d)}finally{B=void 0}}function i(a){B&&(B.debugger&&B.debugger(a),c(B,a))}function j(a){d(a).forEach(k,a)}function k(a){a.debugger&&a.debugger(this),'function'==typeof a.scheduler?a.scheduler(a):'object'==typeof a.scheduler?a.scheduler.add(a):a()}function l(){return B!==void 0}function m(a,b={}){const c=a[C]?a:function b(){return h(b,a,this,arguments)};return c.scheduler=b.scheduler,c.debugger=b.debugger,c[C]=!0,b.lazy||c(),c}function n(a){a.unobserved||(a.unobserved=!0,f(a)),'object'==typeof a.scheduler&&a.scheduler.delete(a)}function o(a){return'function'==typeof Node&&a instanceof Node?!1:!J.has(a.constructor)}function p(a){return K.get(a.constructor)}function q(a,b,c){const d=Reflect.get(a,b,c);return'symbol'==typeof b||'function'==typeof d?d:(i({target:a,key:b,receiver:c,type:'get'}),l()&&'object'==typeof d&&null!==d?v(d):E.get(d)||d)}function r(a,b){const c=Reflect.has(a,b);return'symbol'==typeof b?c:(i({target:a,key:b,type:'has'}),c)}function s(a){return i({target:a,type:'iterate'}),Reflect.ownKeys(a)}function t(a,b,c,d){'object'==typeof c&&null!==c&&(c=D.get(c)||c);const e=L.call(a,b),f=a[b],g=Reflect.set(a,b,c,d);return l()?(console.error(`Mutating observables in reactions is forbidden. You set ${b} to ${c}.`),g):'symbol'==typeof b||a!==D.get(d)?g:(e?c!==f&&j({target:a,key:b,value:c,oldValue:f,receiver:d,type:'set'}):j({target:a,key:b,value:c,receiver:d,type:'add'}),g)}function u(a,b){const c=L.call(a,b),d=a[b],e=Reflect.deleteProperty(a,b);return'symbol'!=typeof b&&c&&j({target:a,key:b,oldValue:d,type:'delete'}),e}function v(a={}){return D.has(a)||!o(a)?a:E.get(a)||w(a)}function w(a){const c=p(a)||M,d=new Proxy(a,c);return E.set(a,d),D.set(d,a),b(a),d}function x(a){return D.has(a)}function y(a){return D.get(a)||a}const z=new WeakMap,A=Symbol('iteration key');let B;const C=Symbol('is reaction'),D=new WeakMap,E=new WeakMap,F=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty,H={has(a){const b=D.get(this),c=F(this);return i({target:b,key:a,type:'has'}),c.has.apply(b,arguments)},get(a){const b=D.get(this),c=F(this);return i({target:b,key:a,type:'get'}),c.get.apply(b,arguments)},add(a){const b=D.get(this),c=F(this),d=c.has.call(b,a),e=c.add.apply(b,arguments);return d||j({target:b,key:a,value:a,type:'add'}),e},set(a,b){const c=D.get(this),d=F(this),e=d.has.call(c,a),f=d.get.call(c,a),g=d.set.apply(c,arguments);return e?b!==f&&j({target:c,key:a,value:b,oldValue:f,type:'set'}):j({target:c,key:a,value:b,type:'add'}),g},delete(a){const b=D.get(this),c=F(this),d=c.has.call(b,a),e=c.get?c.get.call(b,a):void 0,f=c.delete.apply(b,arguments);return d&&j({target:b,key:a,oldValue:e,type:'delete'}),f},clear(){const a=D.get(this),b=F(this),c=0!==a.size,d=a instanceof Map?new Map(a):new Set(a),e=b.clear.apply(a,arguments);return c&&j({target:a,oldTarget:d,type:'clear'}),e},forEach(){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b.forEach.apply(a,arguments)},keys(){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b.keys.apply(a,arguments)},values(){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b.values.apply(a,arguments)},entries(){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b.entries.apply(a,arguments)},[Symbol.iterator](){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),b[Symbol.iterator].apply(a,arguments)},get size(){const a=D.get(this),b=F(this);return i({target:a,type:'iterate'}),Reflect.get(b,'size',a)}};var I={get(a,b,c){return a=G.call(H,b)?H:a,Reflect.get(a,b,c)}};const J=new Set([Date,RegExp]),K=new Map([[Map,I],[Set,I],[WeakMap,I],[WeakSet,I]]),L=Object.prototype.hasOwnProperty;var M={get:q,has:r,ownKeys:s,set:t,deleteProperty:u};a.observe=m,a.unobserve=n,a.observable=v,a.isObservable=x,a.raw=y,Object.defineProperty(a,'__esModule',{value:!0})});
{
"name": "@nx-js/observer-util",
"version": "4.0.1",
"version": "4.1.0",
"description": "Simple transparent reactivity with 100% language coverage. Made with ES6 Proxies.",
"main": "dist/cjs.es5.js",
"module": "dist/es.es5.js",
"types": "types/index.d.ts",
"files": [
"dist"
"dist",
"types"
],

@@ -10,0 +12,0 @@ "scripts": {

@@ -363,4 +363,6 @@ # The Observer Utility

- `scheduler`: A function, which is called with the reaction when it is scheduled to run. It can also be an object with an `add` and `delete` method - which schedule and unschedule reactions. The default scheduler runs the reaction synchronously on related observable mutations.
- `scheduler`: A function, which is called with the reaction when it is scheduled to run. It can also be an object with an `add` and `delete` method - which schedule and unschedule reactions. The default scheduler runs the reaction synchronously on observable mutations. You can learn more about reaction scheduling in the [related docs section](#reaction-scheduling).
- `debugger`: An optional function. It is called with contextual metadata object on basic operations - like set, get, delete, etc. The metadata object can be used to determine why the operation wired or scheduled the reaction and it always has enough data to reverse the operation. The debugger is always called before the scheduler.
### unobserve(reaction)

@@ -367,0 +369,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc