UNPKG

active-data

Version:

Reactive data manager, inspired by MobX. Automatically detects associated data and perform updates to your views or everything dependent on that data when it changes. Implemented with js Proxy objects

1 lines 26.8 kB
{"version":3,"sources":["./src/active-data.js"],"names":["privateMap","WeakMap","initPrivate","target","set","$","get","Manager","[object Object]","options","manager","this","$$","gen","intentToRun","dataSourceKey","Symbol","observables","enabled","u","l","p","h","m","g","getTime","performance","now","Date","callStack","reactionsToUpdate","Set","setOptions","makeObservable","bind","makeReaction","makeComputed","makeUpdatable","mapProperties","isObservable","getDataSource","observable","reaction","computed","updatable","process","env","NODE_ENV","source","propertyKeys","concat","Object","keys","forEach","propertyKey","defineProperty","T","Reflect","value","assign","dataSource","constructor","Array","isArray","toUpdate","Map","computedProperties","propertyDescriptor","getOwnPropertyDescriptor","invalidateDeps","updatableState","invalidIteration","onInvalidate","valid","deps","clear","initUpdates","updatableStates","watchDeepSection","registerRead","currentKey","watchDeepKey","watchKey","key","call","has","add","uninitMap","delete","size","ctrl","G","H","J","updateProperty","invalidatorFn","values","updatableStatesWatch","inRunSection","immediateReaction","run","runDeferred","Proxy","context","length","apply","thisArg","argumentsList","includes","deleteProperty","fn","settings","originalFn","onUninit","id","active","q","Z","undefined","B","F","_","uninitCall","updatableFunction","computing","console","warn","uninit","push","pop","invalidate","getter","setter","ne","action","runScheduled","iterations","maxIterations","Error","startTime","reactions","timeLimit","afterRun","timeout","setTimeout","default"],"mappings":"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","sourcesContent":["/* global process */\n\nconst privateMap = new WeakMap();\nconst initPrivate = target => privateMap.set(target, {});\nconst $ = target => privateMap.get(target);\n\n/**\n * Reactive data manager that observes data changes and performs actions in response.\n * Observation is lazy, data is updated only when required.\n *\n * @param {ManagerOptions} [options] Manager options\n */\nexport class Manager {\n\tconstructor (options) {\n\t\tconst manager = this;\n\t\tinitPrivate(manager);\n\t\tconst $$ = $(manager);\n\t\t$$.gen = 0;\n\t\t$$.intentToRun = 0;\n\t\t$$.dataSourceKey = Symbol(\"dataSource\");\n\t\t$$.observables = new WeakMap();\n\t\t$$.options = {\n\t\t\tenabled: true,\n\t\t\timmediateReaction: false,\n\t\t\tmaxIterations: 10,\n\t\t\twatchKey: \"$$watch\",\n\t\t\twatchDeepKey: \"$$watchDeep\",\n\t\t\tafterRun: null,\n\t\t\ttimeLimit: 50,\n\t\t\tgetTime: typeof performance !== \"undefined\" ? () => performance.now() : () => Date.now(),\n\t\t};\n\t\t$$.callStack = [];\n\t\t$$.reactionsToUpdate = new Set();\n\n\t\tmanager.setOptions(options);\n\t\tmanager.makeObservable = manager.makeObservable.bind(manager);\n\t\tmanager.makeReaction = manager.makeReaction.bind(manager);\n\t\tmanager.makeComputed = manager.makeComputed.bind(manager);\n\t\tmanager.makeUpdatable = manager.makeUpdatable.bind(manager);\n\t\tmanager.mapProperties = manager.mapProperties.bind(manager);\n\n\t\tmanager.isObservable = manager.isObservable.bind(manager);\n\t\tmanager.getDataSource = manager.getDataSource.bind(manager);\n\t\t// aliases\n\t\tmanager.observable = manager.makeObservable;\n\t\tmanager.reaction = manager.makeReaction;\n\t\tmanager.computed = manager.makeComputed;\n\t\tmanager.updatable = manager.makeUpdatable;\n\t\t/* istanbul ignore next */\n\t\tif (typeof process !== \"undefined\" && process.env.NODE_ENV === \"test\") {\n\t\t\tmanager.$$ = $$;\n\t\t}\n\t}\n\n\t/**\n\t * Maps properties from `source` to `target`\n\t *\n\t * @param {Observable} source\n\t * @param {Observable} target\n\t * @param {(Array|String)} [propertyKeys] property keys of `source` object to map to `target` object, if not set then all keys will be mapped\n\t */\n\tmapProperties (source, target, propertyKeys) {\n\t\t[].concat(propertyKeys || Object.keys(source)).forEach(propertyKey => {\n\t\t\tObject.defineProperty(target, propertyKey, {\n\t\t\t\tenumerable: true,\n\t\t\t\tget () {\n\t\t\t\t\treturn Reflect.get(source, propertyKey, this);\n\t\t\t\t},\n\t\t\t\tset (value) {\n\t\t\t\t\treturn Reflect.set(source, propertyKey, value, this);\n\t\t\t\t},\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Dynamically sets the options of the data manager\n\t *\n\t * @param {ManagerOptions} [options] Manager options\n\t */\n\tsetOptions (options = {}) {\n\t\t$(this).options = Object.assign($(this).options, options);\n\t}\n\n\t/**\n\t * Gets the options of the data manager\n\t *\n\t * @return {ManagerOptions} Manager options\n\t */\n\tgetOptions () {\n\t\treturn Object.assign({}, $(this).options);\n\t}\n\n\t/**\n\t * Creates {@link Observable} object for the specified dataSource\n\t *\n\t * @param {(Object|Array)} dataSource data source\n\t * @return {Observable} observable object\n\t */\n\tmakeObservable (dataSource) {\n\t\tconst manager = this;\n\t\tconst $$ = $(manager);\n\t\tif (!dataSource) {\n\t\t\treturn dataSource;\n\t\t}\n\t\tif (\n\t\t\tdataSource.constructor !== Object\n\t\t\t&&\tdataSource.constructor !== Array\n\t\t\t&&\ttypeof dataSource !== \"function\"\n\t\t) {\n\t\t\treturn dataSource;\n\t\t}\n\n\t\tif (manager.isObservable(dataSource)) {\n\t\t\treturn dataSource;\n\t\t}\n\t\tconst isArray = Array.isArray(dataSource);\n\t\tlet observable = $$.observables.get(dataSource);\n\t\tif (!observable) {\n\t\t\tconst toUpdate = new Map();\n\t\t\tconst computedProperties = {};\n\n\t\t\tObject.keys(dataSource).forEach(propertyKey => {\n\t\t\t\tconst propertyDescriptor = Object.getOwnPropertyDescriptor(dataSource, propertyKey);\n\t\t\t\tif (propertyDescriptor && typeof propertyDescriptor.get === \"function\") {\n\t\t\t\t\tcomputedProperties[propertyKey] = manager.makeUpdatable(propertyDescriptor.get);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst invalidateDeps = updatableState => {\n\t\t\t\tupdatableState.invalidIteration = true;\n\t\t\t\tupdatableState.onInvalidate && updatableState.onInvalidate();\n\t\t\t\tif (updatableState.valid) {\n\t\t\t\t\tupdatableState.valid = false;\n\t\t\t\t\tupdatableState.deps.forEach(updatableState =>\n\t\t\t\t\t\tinvalidateDeps(updatableState)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tupdatableState.deps.clear();\n\t\t\t};\n\n\t\t\tconst initUpdates = propertyKey => {\n\t\t\t\tconst updatableStates = new Set();\n\t\t\t\ttoUpdate.set(propertyKey, updatableStates);\n\t\t\t\treturn updatableStates;\n\t\t\t};\n\t\t\tlet watchDeepSection = false;\n\t\t\tconst registerRead = (updatableState, propertyKey) => {\n\t\t\t\tconst currentKey = propertyKey === $$.options.watchDeepKey ? $$.options.watchKey : propertyKey;\n\t\t\t\tif (propertyKey === $$.options.watchDeepKey) {\n\t\t\t\t\tif (watchDeepSection) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\twatchDeepSection = true;\n\t\t\t\t\tObject.keys(dataSource).forEach(key => {\n\t\t\t\t\t\tif (typeof dataSource[key] === \"object\") {\n\t\t\t\t\t\t\tconst obs = manager.makeObservable(dataSource[key]);\n\t\t\t\t\t\t\tobs[$$.options.watchDeepKey];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\twatchDeepSection = false;\n\t\t\t\t}\n\t\t\t\tif (currentKey === $$.options.watchKey) {\n\t\t\t\t\tObject.keys(computedProperties).forEach(key => {\n\t\t\t\t\t\tcomputedProperties[key].call(observable);\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst updatableStates = toUpdate.get(currentKey) || initUpdates(currentKey);\n\t\t\t\tif (!updatableStates.has(updatableState)) {\n\t\t\t\t\tupdatableStates.add(updatableState);\n\t\t\t\t\tupdatableState.uninitMap.set(dataSource, updatableState => {\n\t\t\t\t\t\tupdatableStates.delete(updatableState);\n\t\t\t\t\t\tif (updatableStates.size === 0) {\n\t\t\t\t\t\t\ttoUpdate.delete(currentKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconst ctrl = {toUpdate, dataSource, registerRead};\n\n\t\t\tconst updateProperty = (propertyKey) => {\n\t\t\t\tconst invalidatorFn = updatableState => invalidateDeps(updatableState);\n\t\t\t\tif (propertyKey == null) {\n\t\t\t\t\t[...ctrl.toUpdate.values()]\n\t\t\t\t\t\t.forEach(updatableStates => updatableStates.forEach(invalidatorFn));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tconst updatableStates = ctrl.toUpdate.get(propertyKey);\n\t\t\t\t\tupdatableStates && updatableStates.forEach(invalidatorFn);\n\t\t\t\t\tconst updatableStatesWatch = ctrl.toUpdate.get($$.options.watchKey);\n\t\t\t\t\tupdatableStatesWatch && updatableStatesWatch.forEach(invalidatorFn);\n\t\t\t\t}\n\n\t\t\t\tif (!$$.inRunSection && $$.intentToRun === 1) {\n\t\t\t\t\tif ($$.options.immediateReaction) {\n\t\t\t\t\t\tmanager.run();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tmanager.runDeferred();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tobservable = new Proxy(dataSource, {\n\t\t\t\tget: (target, propertyKey, context) => {\n\t\t\t\t\tif (propertyKey === $$.dataSourceKey) {\n\t\t\t\t\t\treturn dataSource;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet updatableState;\n\t\t\t\t\tif ($$.callStack.length) {\n\t\t\t\t\t\tupdatableState = $$.callStack[$$.callStack.length - 1];\n\t\t\t\t\t\tregisterRead(updatableState, propertyKey);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tpropertyKey === $$.options.watchKey ||\n\t\t\t\t\t\tpropertyKey === $$.options.watchDeepKey\n\t\t\t\t\t) {\n\t\t\t\t\t\treturn context;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = Reflect.get(target, propertyKey, context);\n\t\t\t\t\tif (isArray && typeof value === \"function\" && propertyKey !== \"constructor\") {\n\t\t\t\t\t\treturn new Proxy(value, {\n\t\t\t\t\t\t\tapply: (target, thisArg, argumentsList) => {\n\t\t\t\t\t\t\t\tif ([\"copyWithin\", \"fill\", \"pop\", \"push\", \"reverse\", \"shift\", \"sort\", \"splice\", \"unshift\"].includes(propertyKey)) {\n\t\t\t\t\t\t\t\t\t$$.intentToRun++;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tupdateProperty();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tfinally {\n\t\t\t\t\t\t\t\t\t\t$$.intentToRun--;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn target.apply(dataSource, argumentsList);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn target.apply(thisArg, argumentsList);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typeof value === \"object\") {\n\t\t\t\t\t\treturn manager.makeObservable(value);\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t},\n\t\t\t\tset: (target, propertyKey, value, context) => {\n\n\t\t\t\t\tconst oldValue = Reflect.get(target, propertyKey, context);\n\t\t\t\t\tif (\n\t\t\t\t\t\tvalue !== oldValue ||\n\t\t\t\t\t\t(Array.isArray(target) && propertyKey === \"length\")\n\t\t\t\t\t) {\n\t\t\t\t\t\t$$.intentToRun++;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tReflect.set(target, propertyKey, value, context);\n\t\t\t\t\t\t\tupdateProperty(propertyKey);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinally {\n\t\t\t\t\t\t\t$$.intentToRun--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t\tdefineProperty: (target, propertyKey, propertyDescriptor) => {\n\t\t\t\t\tif (propertyDescriptor && typeof propertyDescriptor.get === \"function\") {\n\t\t\t\t\t\tcomputedProperties[propertyKey] = manager.makeUpdatable(propertyDescriptor.get);\n\t\t\t\t\t}\n\t\t\t\t\treturn Reflect.defineProperty(target, propertyKey, propertyDescriptor);\n\t\t\t\t},\n\t\t\t\tdeleteProperty: (target, propertyKey) => {\n\t\t\t\t\t$$.intentToRun++;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (propertyKey in computedProperties) {\n\t\t\t\t\t\t\tdelete computedProperties[propertyKey];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tupdateProperty(propertyKey);\n\t\t\t\t\t}\n\t\t\t\t\tfinally {\n\t\t\t\t\t\t$$.intentToRun--;\n\t\t\t\t\t}\n\t\t\t\t\treturn Reflect.deleteProperty(target, propertyKey);\n\t\t\t\t},\n\t\t\t});\n\t\t\t$$.observables.set(dataSource, observable);\n\t\t}\n\t\treturn observable;\n\t}\n\n\t/**\n\t * Creates {@link UpdatableFunction}\n\t * Used for internal purposes\n\t *\n\t * @param {Function} fn function that will be called from {@link UpdatableFunction}\n\t * @param {UpdatableSettings} settings settings for updatable function\n\t * @return {UpdatableFunction}\n\t */\n\tmakeUpdatable (fn, settings = {}) {\n\t\tif (fn.originalFn) {\n\t\t\treturn fn;\n\t\t}\n\t\tconst onInvalidate = settings.onInvalidate;\n\t\tconst onUninit = settings.onUninit;\n\n\t\tconst manager = this;\n\t\tconst $$ = $(manager);\n\n\t\tconst updatableState = {\n\t\t\tid: ++$$.gen,\n\t\t\tactive: true,\n\t\t\tvalid: false,\n\t\t\tonInvalidate,\n\t\t\tonUninit,\n\t\t\tvalue: undefined,\n\t\t\tdeps: new Set(),\n\t\t\tuninitMap: new Map(),\n\t\t\tuninit: () => {\n\t\t\t\t[...updatableState.uninitMap.values()].forEach(uninitCall => uninitCall(updatableState));\n\t\t\t\tupdatableState.uninitMap.clear();\n\t\t\t},\n\t\t};\n\n\t\tconst updatableFunction = function () {\n\t\t\tif (!updatableState.active) {\n\t\t\t\treturn fn.call(this, this);\n\t\t\t}\n\t\t\tif (updatableState.computing) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`Detected cross reference inside computed properties!` +\n\t\t\t\t\t\t` \"undefined\" will be returned to prevent infinite loop`\n\t\t\t\t);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif ($$.callStack.length) {\n\t\t\t\tupdatableState.deps.add($$.callStack[$$.callStack.length - 1]);\n\t\t\t}\n\n\t\t\tif (updatableState.valid) {\n\t\t\t\treturn updatableState.value;\n\t\t\t}\n\t\t\tupdatableState.computing = true;\n\t\t\tupdatableState.uninit();\n\n\t\t\t$$.callStack.push(updatableState);\n\t\t\ttry {\n\t\t\t\tconst context = this ? $$.observables.get(this) || this : null;\n\t\t\t\tupdatableState.invalidIteration = false;\n\t\t\t\tconst value = fn.call(context, context);\n\n\t\t\t\tupdatableState.valid = !updatableState.invalidIteration; // check if it was invalidated inside call\n\t\t\t\tupdatableState.value = value;\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tfinally {\n\t\t\t\tupdatableState.computing = false;\n\t\t\t\t$$.callStack.pop();\n\t\t\t}\n\t\t};\n\t\tupdatableFunction.uninit = () => {\n\t\t\tupdatableState.uninit();\n\t\t\tupdatableState.active = false;\n\t\t\tonUninit && onUninit();\n\t\t};\n\t\tupdatableFunction.invalidate = () => {\n\t\t\tupdatableState.valid = false;\n\t\t};\n\t\tupdatableFunction.originalFn = fn;\n\t\treturn updatableFunction;\n\t}\n\n\t/**\n\t * Creates computed property\n\t *\n\t * @param {Object} target The object for which the calculated property will be created\n\t * @param {String} propertyKey Name of calculated property\n\t * @param {Function} getter The function to be executed when accessing the property\n\t * @param {Function} [setter] The function that will be executed when setting the value of the property\n\t */\n\tmakeComputed (target, propertyKey, getter, setter) {\n\t\tObject.defineProperty(target, propertyKey, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\t\t\tget: this.makeUpdatable(getter),\n\t\t\tset: setter,\n\t\t});\n\t}\n\n\t/**\n\t * Creates {@link UpdatableFunction} that will be automatically\n\t * executed when one of it's dependencies are changed\n\t *\n\t * @param {Function} call\n\t * Function to call {@link UpdatableFunction}\n\t * 'call' will be executed when some of {@link Observable} that was used on previous call\n\t * are changed\n\t *\n\t * @param {Boolean} run\n\t * Run function immediately after it's registration\n\t * If {@link ManagerOptions.immediateReaction} is not set\n\t * then it will be called on the next tick.\n\t * @return {UpdatableFunction}\n\t */\n\tmakeReaction (call, run = true) {\n\t\tconst manager = this;\n\t\tconst $$ = $(manager);\n\t\tconst updatable = manager.makeUpdatable(call, {\n\t\t\tonInvalidate: () => $$.reactionsToUpdate.add(updatable),\n\t\t\tonUninit: () => $$.reactionsToUpdate.delete(updatable),\n\t\t});\n\t\t$$.reactionsToUpdate.add(updatable);\n\t\tif (run) {\n\t\t\tif ($$.options.immediateReaction) {\n\t\t\t\tmanager.run();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tmanager.runDeferred();\n\t\t\t}\n\t\t}\n\t\treturn updatable;\n\t}\n\n\t/**\n\t * Returns original source of {@link Observable}\n\t *\n\t * @return {(Object|Array)}\n\t */\n\tgetDataSource (target) {\n\t\treturn target[$(this).dataSourceKey];\n\t}\n\n\t/**\n\t * Checks if the object is {@link Observable}\n\t *\n\t * @param {(Observable|Object|Array)} target\n\t */\n\tisObservable (target) {\n\t\treturn target[$(this).dataSourceKey] != null;\n\t}\n\n\t/**\n\t * Executes all reactions that marked with invalid state\n\t *\n\t * @param {Function} [action]\n\t * Changes of {@link Observable} that happens inside 'action' function\n\t * will not trigger immediate execution of dependent reactions\n\t * If {@link ManagerOptions.immediateReaction} is set then reactions\n\t * will be executed after exiting the 'action' function\n\t */\n\trun (action) {\n\t\tconst manager = this;\n\t\tconst $$ = $(manager);\n\t\tif (!$$.options.enabled) {\n\t\t\treturn;\n\t\t}\n\t\t$$.inRunSection = true;\n\t\ttry {\n\t\t\tif (typeof action === \"function\") {\n\t\t\t\taction();\n\t\t\t}\n\t\t\t$$.runScheduled = false;\n\t\t\tlet iterations = 0;\n\t\t\twhile ($$.reactionsToUpdate.size) {\n\t\t\t\tif (iterations > $$.options.maxIterations) {\n\t\t\t\t\t$$.reactionsToUpdate.clear();\n\t\t\t\t\tthrow new Error(\"Max iterations exceeded!\");\n\t\t\t\t}\n\t\t\t\titerations++;\n\t\t\t\tconst startTime = $$.options.getTime();\n\t\t\t\tconst reactions = [...$$.reactionsToUpdate.values()];\n\t\t\t\tfor (const updatable of reactions) {\n\t\t\t\t\t$$.reactionsToUpdate.delete(updatable);\n\t\t\t\t\tupdatable();\n\t\t\t\t\tif ($$.options.getTime() - startTime >= $$.options.timeLimit) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($$.reactionsToUpdate.size) {\n\t\t\t\t\tmanager.runDeferred();\n\t\t\t\t}\n\t\t\t}\n\t\t\ttypeof $$.options.afterRun === \"function\" && $$.options.afterRun();\n\t\t}\n\t\tfinally {\n\t\t\t$$.inRunSection = false;\n\t\t}\n\t}\n\n\t/**\n\t * Executes all reactions that marked as invalid\n\t * Unlike {@link run}, 'runDeferred' makes it not immediately but after 'timeout'\n\t *\n\t * @param {Function} [action] changes of {@link Observable} that happens inside 'action' function\n\t * will not trigger immediate execution of dependent reactions\n\t * @param {Number} [timeout=0] reactions execution delay\n\t */\n\trunDeferred (action, timeout = 0) {\n\t\tconst manager = this;\n\t\tconst $$ = $(manager);\n\t\tif (!$$.options.enabled) {\n\t\t\treturn;\n\t\t}\n\t\t$$.inRunSection = true;\n\t\ttry {\n\t\t\tif (!$$.runScheduled) {\n\t\t\t\t$$.runScheduled = setTimeout(() => this.run(), timeout);\n\t\t\t}\n\t\t\tif (typeof action === \"function\") {\n\t\t\t\taction();\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\t$$.inRunSection = false;\n\t\t}\n\t}\n}\n\nManager.default = new Manager();\nManager.default.Manager = Manager;\n\nexport default Manager.default;\nexport const observable = Manager.default.observable;\nexport const reaction = Manager.default.reaction;\nexport const computed = Manager.default.computed;\nexport const updatable = Manager.default.updatable;\n\n/**\n * @typedef ManagerOptions\n * @name ManagerOptions\n * @type {Object}\n * @property {Boolean} [immediateReaction=false] if set to `true` reactions will be executed immediately on same event loop\n * otherwise it will be executed after zero timeout (on next event loop)\n * @property {Boolean} [enabled=true] - state of data manager, if it is disabled then reactions will not be executed\n */\n\n/**\n * @typedef Observable\n * @name Observable\n * @description Object or array that will be observed for changes.\n * When the property of type {@link Object} or {@link Array} of {@link Observable}\n * are accessed it automaticaly becomes {@link Observable}\n */\n\n/**\n * @typedef UpdatableFunction\n * @name UpdatableFunction\n * @property {Function} uninit\n * @description function that caches result of its execution and returns cached value if function state is valid\n * function state can be invalidated if some of {@link Observable} objects that were accessed on previous call are changed\n */\n\n/**\n * @typedef UpdatableSettings\n * @name UpdatableSettings\n * @type {Object}\n * @property {Function} onInvalidate callback function that will be executed when UpdatableState of {@link UpdatableFunction} becomes invalid\n * @property {Function} onUninit callback function that will be executed after {@link UpdatableFunction#uninit} is called\n * @description Settings to create {@link UpdatableFunction}\n */\n"]}