Socket
Socket
Sign inDemoInstall

mobservable

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mobservable - npm Package Compare versions

Comparing version 1.0.0-alpha.6 to 1.0.0

.vscode/launch.json

46

CHANGELOG.md
# 1.0
* Introduces a second `strictMode` parameter to transaction.
* dropped the default export of observable
* Fixes issue where non-`strict` mode and `logLevel` where not always honored.
## Renames
* `isReactive` -> `isObservable`
* `makeReactive` -> `observable`
* `extendReactive` -> `extendObservable`
* `observe` -> `autorun`
* `observeUntil` -> `autorunUntil`
* `observeAsync` -> `autorunAsync`
* `reactiveComponent` -> `observer` (in `mobservable-react` package)
## Breaking changes
* dropped the `strict` and `logLevel` settings of mobservable. View functions are by default run in `strict` mode, `autorun` (formerly: `observe`) functions in `non-strict` mode (strict indicates that it is allowed to change other observable values during the computation of a view funtion).
Use `extras.withStrict(boolean, block)` if you want to deviate from the default behavior.
* `observable` (formerly `makeReactive`) no longer accepts an options object. The modifiers `asReference`, `asStructure` and `asFlat` can be used instead.
* dropped the `default` export of observable
* Removed all earlier deprecated functions
## Bugfixes / improvements
* `mobservable` now ships with TypeScript 1.6 compliant module typings, no external typings file is required anymore.
* `mobservable-react` supports React Native as well through the import `"mobservable-react/native"`.
* Improved debugger support
* `for (var key in observablearray)` now lists the correct keys
* `@observable` now works correct on classes that are transpiled by either TypeScript or Babel (Not all constructions where supported in Babel earlier)
* Simplified error handling, mobservable will no longer catch errors in views, which makes the stack traces easier to debug.
* Removed the initial 'welcom to mobservable' logline that was printed during start-up.
# 0.7.1
* Backported Babel support for the @observable decorator from the 1.0 branch. The decorator should now behave the same when compiled with either Typescript or Babeljs.
# 0.7.0
* Introduced `strict` mode (see issues #30, #31)
* Introduced `strict` mode (see issues [#30](), [#31]())
* Renamed `sideEffect` to `observe`

@@ -14,10 +42,14 @@ * Renamed `when` to `observeUntil`

* Fixed issue where changing the `logLevel` was not picked up.
* Improved typings (will be distributed through DefinitelyTyped in the near future)
* Introduces `asStructure` (see #8) and `asFlat`.
* Improved typings.
* Introduces `asStructure` (see [#8]()) and `asFlat`.
* Assigning a plain object to a reactive structure no longer clones the object, instead, the original object is decorated. (Arrays are still cloned due to Javascript limitations to extend arrays).
* Reintroduced `expr(func)` as shorthand for `makeReactive(func)()`, which is useful to create temporarily views inside views
* Deprecated the options object that could be passed to `makeReactive`.
* Deprecated the options object that could be passed to `makeReactive`:
* A `thisArg` can be passed as second param.
* A name (for debugging) can be passed as second or third param
* The `as` modifier is no longer needed, use `asReference` (instead of `as:'reference'`) or `asFlat` (instead of `recurse:false`).
# 0.6.10
# 0.6.10
* Fixed issue where @observable did not properly create a stand-alone view

@@ -24,0 +56,0 @@

338

dist/mobservable.js

@@ -85,14 +85,2 @@ (function webpackUniversalModuleDefinition(root, factory) {

exports.observeAsync = core_1.autorunAsync;
Object.defineProperties(module.exports, {
strict: {
enumerable: true,
get: core.getStrict,
set: core.setStrict
},
logLevel: {
enumerable: true,
get: core.getLogLevel,
set: core.setLogLevel
}
});
exports._ = {

@@ -107,3 +95,4 @@ isComputingView: dnode_1.isComputingView,

trackTransitions: extras_1.trackTransitions,
SimpleEventEmitter: simpleeventemitter_1.default
SimpleEventEmitter: simpleeventemitter_1.default,
withStrict: core.withStrict
};

@@ -183,4 +172,2 @@

});
if (logLevel >= 2 && observable.observing.length === 0)
console.warn("[mobservable.observe] not a single observable was used inside the observing function. This observer is now a no-op.");
disposer.$mobservable = observable;

@@ -263,6 +250,6 @@ return disposer;

descriptor.get = function () {
var baseStrict = strict;
strict = false;
observableobject_1.ObservableObject.asReactive(this, null, ValueMode.Recursive).set(key, baseValue);
strict = baseStrict;
var _this = this;
withStrict(false, function () {
observableobject_1.ObservableObject.asReactive(_this, null, ValueMode.Recursive).set(key, baseValue);
});
return this[key];

@@ -297,16 +284,7 @@ };

exports.toJSON = toJSON;
function transaction(action, strict) {
return scheduler_1.transaction(action, strict);
function transaction(action) {
return scheduler_1.transaction(action);
}
exports.transaction = transaction;
var logLevel = 1;
function getLogLevel() {
return logLevel;
}
exports.getLogLevel = getLogLevel;
function setLogLevel(newLogLevel) {
logLevel = newLogLevel;
}
exports.setLogLevel = setLogLevel;
var strict = true;
var strict = false;
function getStrict() {

@@ -316,10 +294,13 @@ return strict;

exports.getStrict = getStrict;
function setStrict(newStrict) {
function withStrict(newStrict, func) {
var baseStrict = strict;
strict = newStrict;
try {
func();
}
finally {
strict = baseStrict;
}
}
exports.setStrict = setStrict;
setTimeout(function () {
if (logLevel > 0)
console.info("Welcome to mobservable. Current logLevel = " + logLevel + ". Change mobservable.logLevel according to your needs: 0 = production, 1 = development, 2 = debugging. Strict mode is " + (strict ? 'enabled' : 'disabled') + ".");
}, 1);
exports.withStrict = withStrict;
(function (ValueType) {

@@ -435,3 +416,3 @@ ValueType[ValueType["Reference"] = 0] = "Reference";

if (Array.isArray(value))
return new observablearray_1.ObservableArray(value.slice(), childMode, context);
return observablearray_1.createObservableArray(value.slice(), childMode, context);
if (utils_1.isPlainObject(value))

@@ -444,4 +425,2 @@ return extendObservableHelper(value, value, childMode, context);

function assertUnwrapped(value, message) {
if (logLevel === 0)
return;
if (value instanceof AsReference || value instanceof AsStructure || value instanceof AsFlat)

@@ -473,5 +452,5 @@ throw new Error("[mobservable] asStructure / asReference / asFlat cannot be used here. " + message);

function checkIfStateIsBeingModifiedDuringView(context) {
if (core_1.getLogLevel() > 0 && isComputingView() && core_1.getStrict() === true) {
if (core_1.getStrict() === true && isComputingView()) {
var ts = __mobservableViewStack;
throw new Error("[mobservable] It is not allowed to change the state during the computation of a reactive view if 'mobservable.strict' mode is enabled:\nShould the data you are trying to modify actually be a view?\nView name: " + context.name + ".\nCurrent stack size is " + ts.length + ", active view: \"" + ts[ts.length - 1].toString() + "\".");
throw new Error("[mobservable] It is not allowed to change the state during the computation of a reactive view. Should the data you are trying to modify actually be a view? \nUse 'mobservable.extras.withStrict(false, block)' to allow changes to be made inside views (unrecommended).\nView name: " + context.name + ".\nCurrent stack size is " + ts.length + ", active view: \"" + ts[ts.length - 1].toString() + "\".");
}

@@ -611,2 +590,3 @@ }

ViewNode.prototype.computeNextState = function () {
var _this = this;
this.trackDependencies();

@@ -617,3 +597,6 @@ if (extras_1.transitionTracker)

try {
var stateDidChange = this.compute();
var stateDidChange;
core_1.withStrict(this.externalRefenceCount === 0, function () {
stateDidChange = _this.compute();
});
hasError = false;

@@ -639,5 +622,2 @@ }

__mobservableViewStack.length -= 1;
if (this.observing.length === 0 && core_1.getLogLevel() > 1 && !this.isDisposed) {
console.error("[mobservable] You have created a view function that doesn't observe any values, did you forget to make its dependencies observable?");
}
var _a = utils_1.quickDiff(this.observing, this.prevObserving), added = _a[0], removed = _a[1];

@@ -648,3 +628,3 @@ this.prevObserving = null;

var dependency = added[i];
if (core_1.getLogLevel() > 0 && dependency instanceof ViewNode && dependency.findCycle(this)) {
if (dependency instanceof ViewNode && dependency.findCycle(this)) {
this.hasCycle = true;

@@ -855,3 +835,12 @@ this.observing.splice(this.observing.indexOf(added[i]), 1);

this.values[propName] = observable;
Object.defineProperty(this.target, propName, observable.asPropertyDescriptor());
Object.defineProperty(this.target, propName, {
configurable: true,
enumerable: observable instanceof observablevalue_1.ObservableValue,
get: function () {
return this.$mobservable ? this.$mobservable.values[propName].get() : undefined;
},
set: function (newValue) {
this.$mobservable.values[propName].set(newValue);
}
});
};

@@ -946,11 +935,2 @@ return ObservableObject;

};
ObservableView.prototype.asPropertyDescriptor = function () {
var _this = this;
return {
configurable: false,
enumerable: false,
get: function () { return _this.get(); },
set: throwingViewSetter(this.context.name)
};
};
ObservableView.prototype.toString = function () {

@@ -1022,3 +1002,2 @@ return "ComputedObservable[" + this.context.name + ":" + this._value + "] " + this.func.toString();

*/
var observablearray_1 = __webpack_require__(8);
function once(func) {

@@ -1047,2 +1026,13 @@ var invoked = false;

exports.isPlainObject = isPlainObject;
function makeNonEnumerable(object, props) {
for (var i = 0; i < props.length; i++) {
Object.defineProperty(object, props[i], {
configurable: true,
writable: true,
enumerable: false,
value: object[props[i]]
});
}
}
exports.makeNonEnumerable = makeNonEnumerable;
function deepEquals(a, b) {

@@ -1126,2 +1116,3 @@ if (a === null && b === null)

exports.quickDiff = quickDiff;
var observablearray_1 = __webpack_require__(8);

@@ -1143,6 +1134,6 @@

};
var utils_1 = __webpack_require__(7);
var dnode_1 = __webpack_require__(2);
var simpleeventemitter_1 = __webpack_require__(6);
var core_1 = __webpack_require__(1);
var utils_1 = __webpack_require__(7);
var StubArray = (function () {

@@ -1166,53 +1157,34 @@ function StubArray() {

}
return ObservableArrayAdministration;
})(dnode_1.DataNode);
exports.ObservableArrayAdministration = ObservableArrayAdministration;
var ObservableArray = (function (_super) {
__extends(ObservableArray, _super);
function ObservableArray(initialValues, mode, context) {
_super.call(this);
Object.defineProperty(this, "$mobservable", {
enumerable: false,
configurable: false,
value: new ObservableArrayAdministration(this, mode, context)
});
if (initialValues && initialValues.length)
this.replace(initialValues);
}
Object.defineProperty(ObservableArray.prototype, "length", {
get: function () {
this.$mobservable.notifyObserved();
return this.$mobservable.values.length;
},
set: function (newLength) {
if (typeof newLength !== "number" || newLength < 0)
throw new Error("[mobservable.array] Out of range: " + newLength);
var currentLength = this.$mobservable.values.length;
if (newLength === currentLength)
return;
else if (newLength > currentLength)
this.spliceWithArray(currentLength, 0, new Array(newLength - currentLength));
else
this.spliceWithArray(newLength, currentLength - newLength);
},
enumerable: true,
configurable: true
});
ObservableArray.prototype.updateLength = function (oldLength, delta) {
ObservableArrayAdministration.prototype.getLength = function () {
this.notifyObserved();
return this.values.length;
};
ObservableArrayAdministration.prototype.setLength = function (newLength) {
if (typeof newLength !== "number" || newLength < 0)
throw new Error("[mobservable.array] Out of range: " + newLength);
var currentLength = this.values.length;
if (newLength === currentLength)
return;
else if (newLength > currentLength)
this.spliceWithArray(currentLength, 0, new Array(newLength - currentLength));
else
this.spliceWithArray(newLength, currentLength - newLength);
};
ObservableArrayAdministration.prototype.updateLength = function (oldLength, delta) {
if (delta < 0) {
dnode_1.checkIfStateIsBeingModifiedDuringView(this.$mobservable.context);
dnode_1.checkIfStateIsBeingModifiedDuringView(this.context);
for (var i = oldLength + delta; i < oldLength; i++)
delete this[i];
delete this.array[i];
}
else if (delta > 0) {
dnode_1.checkIfStateIsBeingModifiedDuringView(this.$mobservable.context);
dnode_1.checkIfStateIsBeingModifiedDuringView(this.context);
if (oldLength + delta > OBSERVABLE_ARRAY_BUFFER_SIZE)
reserveArrayBuffer(oldLength + delta);
for (var i = oldLength, end = oldLength + delta; i < end; i++)
Object.defineProperty(this, "" + i, ENUMERABLE_PROPS[i]);
Object.defineProperty(this.array, i, ENUMERABLE_PROPS[i]);
}
};
ObservableArray.prototype.spliceWithArray = function (index, deleteCount, newItems) {
ObservableArrayAdministration.prototype.spliceWithArray = function (index, deleteCount, newItems) {
var _this = this;
var length = this.$mobservable.values.length;
var length = this.values.length;
if ((newItems === undefined || newItems.length === 0) && (deleteCount === 0 || length === 0))

@@ -1238,3 +1210,3 @@ return [];

this.updateLength(length, lengthDelta);
var res = (_a = this.$mobservable.values).splice.apply(_a, [index, deleteCount].concat(newItems));
var res = (_a = this.values).splice.apply(_a, [index, deleteCount].concat(newItems));
this.notifySplice(index, res, newItems);

@@ -1244,23 +1216,42 @@ return res;

};
ObservableArray.prototype.makeReactiveArrayItem = function (value) {
ObservableArrayAdministration.prototype.makeReactiveArrayItem = function (value) {
core_1.assertUnwrapped(value, "Array values cannot have modifiers");
return core_1.makeChildObservable(value, this.$mobservable.mode, {
object: this.$mobservable.context.object,
name: this.$mobservable.context.name + "[x]"
return core_1.makeChildObservable(value, this.mode, {
object: this.context.object,
name: this.context.name + "[x]"
});
};
ObservableArray.prototype.notifyChildUpdate = function (index, oldValue) {
ObservableArrayAdministration.prototype.notifyChildUpdate = function (index, oldValue) {
this.notifyChanged();
this.$mobservable.changeEvent.emit({ object: this, type: 'update', index: index, oldValue: oldValue });
this.changeEvent.emit({ object: this.array, type: 'update', index: index, oldValue: oldValue });
};
ObservableArray.prototype.notifySplice = function (index, deleted, added) {
ObservableArrayAdministration.prototype.notifySplice = function (index, deleted, added) {
if (deleted.length === 0 && added.length === 0)
return;
this.notifyChanged();
this.$mobservable.changeEvent.emit({ object: this, type: 'splice', index: index, addedCount: added.length, removed: deleted });
this.changeEvent.emit({ object: this.array, type: 'splice', index: index, addedCount: added.length, removed: deleted });
};
ObservableArray.prototype.notifyChanged = function () {
this.$mobservable.markStale();
this.$mobservable.markReady(true);
ObservableArrayAdministration.prototype.notifyChanged = function () {
this.markStale();
this.markReady(true);
};
return ObservableArrayAdministration;
})(dnode_1.DataNode);
exports.ObservableArrayAdministration = ObservableArrayAdministration;
function createObservableArray(initialValues, mode, context) {
return new ObservableArray(initialValues, mode, context);
}
exports.createObservableArray = createObservableArray;
var ObservableArray = (function (_super) {
__extends(ObservableArray, _super);
function ObservableArray(initialValues, mode, context) {
_super.call(this);
Object.defineProperty(this, "$mobservable", {
enumerable: false,
configurable: false,
value: new ObservableArrayAdministration(this, mode, context)
});
if (initialValues && initialValues.length)
this.replace(initialValues);
}
ObservableArray.prototype.observe = function (listener, fireImmediately) {

@@ -1276,3 +1267,3 @@ if (fireImmediately === void 0) { fireImmediately = false; }

ObservableArray.prototype.replace = function (newItems) {
return this.spliceWithArray(0, this.$mobservable.values.length, newItems);
return this.$mobservable.spliceWithArray(0, this.$mobservable.values.length, newItems);
};

@@ -1301,7 +1292,7 @@ ObservableArray.prototype.toJSON = function () {

case 1:
return this.spliceWithArray(index);
return this.$mobservable.spliceWithArray(index);
case 2:
return this.spliceWithArray(index, deleteCount);
return this.$mobservable.spliceWithArray(index, deleteCount);
}
return this.spliceWithArray(index, deleteCount, newItems);
return this.$mobservable.spliceWithArray(index, deleteCount, newItems);
};

@@ -1313,3 +1304,3 @@ ObservableArray.prototype.push = function () {

}
this.spliceWithArray(this.$mobservable.values.length, 0, items);
this.$mobservable.spliceWithArray(this.$mobservable.values.length, 0, items);
return this.$mobservable.values.length;

@@ -1328,3 +1319,3 @@ };

}
this.spliceWithArray(0, 0, items);
this.$mobservable.spliceWithArray(0, 0, items);
return this.$mobservable.values.length;

@@ -1352,36 +1343,58 @@ };

};
ObservableArray.prototype.concat = function () { throw "Illegal state"; };
ObservableArray.prototype.join = function (separator) { throw "Illegal state"; };
ObservableArray.prototype.slice = function (start, end) { throw "Illegal state"; };
ObservableArray.prototype.indexOf = function (searchElement, fromIndex) { throw "Illegal state"; };
ObservableArray.prototype.lastIndexOf = function (searchElement, fromIndex) { throw "Illegal state"; };
ObservableArray.prototype.every = function (callbackfn, thisArg) { throw "Illegal state"; };
ObservableArray.prototype.some = function (callbackfn, thisArg) { throw "Illegal state"; };
ObservableArray.prototype.forEach = function (callbackfn, thisArg) { throw "Illegal state"; };
ObservableArray.prototype.map = function (callbackfn, thisArg) { throw "Illegal state"; };
ObservableArray.prototype.filter = function (callbackfn, thisArg) { throw "Illegal state"; };
ObservableArray.prototype.reduce = function (callbackfn, initialValue) { throw "Illegal state"; };
ObservableArray.prototype.reduceRight = function (callbackfn, initialValue) { throw "Illegal state"; };
return ObservableArray;
})(StubArray);
exports.ObservableArray = ObservableArray;
utils_1.makeNonEnumerable(ObservableArray.prototype, [
"constructor",
"clear",
"find",
"observe",
"pop",
"push",
"remove",
"replace",
"reverse",
"shift",
"sort",
"splice",
"split",
"toJSON",
"toLocaleString",
"toString",
"unshift"
]);
Object.defineProperty(ObservableArray.prototype, "length", {
enumerable: false,
configurable: true,
get: function () {
return this.$mobservable.getLength();
},
set: function (newLength) {
this.$mobservable.setLength(newLength);
}
});
[
"concat",
"every",
"filter",
"forEach",
"indexOf",
"join",
"slice",
"indexOf",
"lastIndexOf",
"every",
"some",
"forEach",
"map",
"filter",
"reduce",
"reduceRight",
"slice",
"some",
].forEach(function (funcName) {
var baseFunc = Array.prototype[funcName];
ObservableArray.prototype[funcName] = function () {
this.$mobservable.notifyObserved();
return baseFunc.apply(this.$mobservable.values, arguments);
};
Object.defineProperty(ObservableArray.prototype, funcName, {
configurable: false,
writable: true,
enumerable: false,
value: function () {
this.$mobservable.notifyObserved();
return baseFunc.apply(this.$mobservable.values, arguments);
}
});
});

@@ -1395,21 +1408,24 @@ var OBSERVABLE_ARRAY_BUFFER_SIZE = 0;

set: function (value) {
var impl = this.$mobservable;
var values = impl.values;
core_1.assertUnwrapped(value, "Modifiers cannot be used on array values. For non-reactive array values use makeReactive(asFlat(array)).");
if (index < this.$mobservable.values.length) {
dnode_1.checkIfStateIsBeingModifiedDuringView(this.$mobservable.context);
var oldValue = this.$mobservable.values[index];
var changed = this.$mobservable.mode === core_1.ValueMode.Structure ? !utils_1.deepEquals(oldValue, value) : oldValue !== value;
if (index < values.length) {
dnode_1.checkIfStateIsBeingModifiedDuringView(impl.context);
var oldValue = values[index];
var changed = impl.mode === core_1.ValueMode.Structure ? !utils_1.deepEquals(oldValue, value) : oldValue !== value;
if (changed) {
this.$mobservable.values[index] = this.makeReactiveArrayItem(value);
this.notifyChildUpdate(index, oldValue);
values[index] = impl.makeReactiveArrayItem(value);
impl.notifyChildUpdate(index, oldValue);
}
}
else if (index === this.$mobservable.values.length)
this.push(this.makeReactiveArrayItem(value));
else if (index === values.length)
this.push(impl.makeReactiveArrayItem(value));
else
throw new Error("[mobservable.array] Index out of bounds, " + index + " is larger than " + this.$mobservable.values.length);
throw new Error("[mobservable.array] Index out of bounds, " + index + " is larger than " + values.length);
},
get: function () {
if (this.$mobservable && index < this.$mobservable.values.length) {
this.$mobservable.notifyObserved();
return this.$mobservable.values[index];
var impl = this.$mobservable;
if (impl && index < impl.values.length) {
impl.notifyObserved();
return impl.values[index];
}

@@ -1484,11 +1500,2 @@ return undefined;

};
ObservableValue.prototype.asPropertyDescriptor = function () {
var _this = this;
return {
configurable: false,
enumerable: true,
get: function () { return _this.get(); },
set: function (value) { return _this.set(value); }
};
};
ObservableValue.prototype.toString = function () {

@@ -1504,5 +1511,4 @@ return "Observable[" + this.context.name + ":" + this._value + "]";

/* 10 */
/***/ function(module, exports, __webpack_require__) {
/***/ function(module, exports) {
var core = __webpack_require__(1);
var inBatch = 0;

@@ -1531,7 +1537,4 @@ var tasks = [];

}
function transaction(action, strict) {
var preStrict = core.getStrict();
function transaction(action) {
inBatch += 1;
if (strict !== undefined)
core.setStrict(strict);
try {

@@ -1546,3 +1549,2 @@ return action();

}
core.setStrict(preStrict);
}

@@ -1549,0 +1551,0 @@ }

@@ -19,7 +19,5 @@ import { Lambda, IObservableArray, IObservableValue, IContextInfoStruct } from './interfaces';

export declare function toJSON(source: any): any;
export declare function transaction<T>(action: () => T, strict?: boolean): T;
export declare function getLogLevel(): number;
export declare function setLogLevel(newLogLevel: any): void;
export declare function transaction<T>(action: () => T): T;
export declare function getStrict(): boolean;
export declare function setStrict(newStrict: any): void;
export declare function withStrict(newStrict: boolean, func: Lambda): void;
export declare enum ValueType {

@@ -26,0 +24,0 @@ Reference = 0,

@@ -5,4 +5,2 @@ import { IDependencyTree, IObserverTree, ITransitionEvent, Lambda } from './interfaces';

export { isObservable, observable, extendObservable, asReference, asFlat, asStructure, autorun, autorunUntil, autorunAsync, expr, transaction, toJSON, isObservable as isReactive, observable as makeReactive, extendObservable as extendReactive, autorun as observe, autorunUntil as observeUntil, autorunAsync as observeAsync } from './core';
export declare var strict: boolean;
export declare var logLevel: number;
export declare const _: {

@@ -18,2 +16,3 @@ isComputingView: () => boolean;

SimpleEventEmitter: typeof SimpleEventEmitter;
withStrict: (newStrict: boolean, func: Lambda) => void;
};

@@ -13,8 +13,4 @@ import { DataNode } from './dnode';

constructor(array: ObservableArray<T>, mode: ValueMode, context: IContextInfoStruct);
}
export declare class ObservableArray<T> extends StubArray implements IObservableArray<T> {
[n: number]: T;
$mobservable: ObservableArrayAdministration<T>;
constructor(initialValues: T[], mode: ValueMode, context: IContextInfoStruct);
length: number;
getLength(): number;
setLength(newLength: any): number;
private updateLength(oldLength, delta);

@@ -26,2 +22,7 @@ spliceWithArray(index: number, deleteCount?: number, newItems?: T[]): T[];

private notifyChanged();
}
export declare function createObservableArray<T>(initialValues: T[], mode: ValueMode, context: IContextInfoStruct): IObservableArray<T>;
export declare class ObservableArray<T> extends StubArray {
$mobservable: ObservableArrayAdministration<T>;
constructor(initialValues: T[], mode: ValueMode, context: IContextInfoStruct);
observe(listener: (changeData: IArrayChange<T> | IArraySplice<T>) => void, fireImmediately?: boolean): Lambda;

@@ -42,14 +43,2 @@ clear(): T[];

toLocaleString(): string;
concat<U extends T[]>(...items: U[]): T[];
join(separator?: string): string;
slice(start?: number, end?: number): T[];
indexOf(searchElement: T, fromIndex?: number): number;
lastIndexOf(searchElement: T, fromIndex?: number): number;
every(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
some(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): boolean;
forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
filter(callbackfn: (value: T, index: number, array: T[]) => boolean, thisArg?: any): T[];
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;
}

@@ -15,4 +15,3 @@ import { DataNode } from './dnode';

observe(listener: (newValue: T, oldValue: T) => void, fireImmediately?: boolean): Lambda;
asPropertyDescriptor(): PropertyDescriptor;
toString(): string;
}

@@ -17,4 +17,3 @@ import { ViewNode } from './dnode';

observe(listener: (newValue: T, oldValue: T) => void, fireImmediately?: boolean): Lambda;
asPropertyDescriptor(): PropertyDescriptor;
toString(): string;
}
import { Lambda } from './interfaces';
export declare function schedule(func: Lambda): void;
export declare function transaction<T>(action: () => T, strict?: boolean): T;
export declare function transaction<T>(action: () => T): T;

@@ -1,6 +0,7 @@

import { Lambda } from './interfaces';
export declare function once(func: Lambda): Lambda;
export declare function unique<T>(list: T[]): T[];
export declare function isPlainObject(value: any): boolean;
export declare function makeNonEnumerable(object: any, props: string[]): void;
export declare function deepEquals(a: any, b: any): boolean;
export declare function quickDiff<T>(current: T[], base: T[]): [T[], T[]];
import { Lambda } from './interfaces';
{
"name": "mobservable",
"version": "1.0.0-alpha.6",
"description": "Observable data. Reactive functions. No staleness.",
"main": "dist/mobservable.js",
"typings": "dist/typings/index",
"scripts": {
"test": "npm run build && npm run buildtest && ./node_modules/istanbul/lib/cli.js cover nodeunit test/*.js && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js ",
"start": "npm run build && npm run buildtest && ./node_modules/nodeunit/bin/nodeunit test/*.js",
"prepublish": "npm run build",
"build": "rm -rf dist && mkdir -p dist/typings && ./node_modules/typescript/bin/tsc && NODE_ENV=production ./node_modules/webpack/bin/webpack.js && cp -r .build/*.d.ts dist/typings",
"buildtest": "npm run build-typescript-tests && npm run build-babel-tests",
"build-typescript-tests": "./node_modules/typescript/bin/tsc -m commonjs -t es5 --experimentalDecorators --outDir test test/typescript/typescript-test.ts",
"build-babel-tests": "./node_modules/babel/bin/babel.js --stage 0 test/babel/babel-test.js -o test/babel-test.js",
"perf": "npm run build && ./node_modules/nodeunit/bin/nodeunit test/perf/*.js"
},
"repository": {
"type": "git",
"url": "https://github.com/mweststrate/mobservable.git"
},
"author": "Michel Weststrate",
"license": "MIT",
"bugs": {
"url": "https://github.com/mweststrate/mobservable/issues"
},
"homepage": "https://mweststrate.github.io/mobservable",
"devDependencies": {
"babel": "^5.8.23",
"coveralls": "^2.11.4",
"istanbul": "^0.3.21",
"nodeunit": "^0.9.1",
"nodeunit-browser-tap": "^0.1.0",
"typescript": "^1.6.2",
"webpack": "^1.12.2"
},
"keywords": [
"mobservable",
"observable",
"react-component",
"react",
"reactjs",
"reactive",
"model",
"frp",
"functional-reactive-programming"
]
}
"name": "mobservable",
"version": "1.0.0",
"description": "Observable data. Reactive functions. Simple code.",
"main": "dist/mobservable.js",
"typings": "dist/typings/index",
"scripts": {
"test": "npm run build && npm run buildtest && ./node_modules/istanbul/lib/cli.js cover nodeunit test/*.js && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js ",
"start": "npm run build && npm run buildtest && ./node_modules/nodeunit/bin/nodeunit test/*.js",
"prepublish": "npm run build",
"build": "rm -rf dist && mkdir -p dist/typings && ./node_modules/typescript/bin/tsc && NODE_ENV=production ./node_modules/webpack/bin/webpack.js && cp -r .build/*.d.ts dist/typings",
"buildtest": "npm run build-typescript-tests && npm run build-babel-tests",
"build-typescript-tests": "./node_modules/typescript/bin/tsc -m commonjs -t es5 --experimentalDecorators --outDir test test/typescript/typescript-test.ts",
"build-babel-tests": "./node_modules/babel/bin/babel.js --stage 0 test/babel/babel-test.js -o test/babel-test.js",
"perf": "npm run build && ./node_modules/nodeunit/bin/nodeunit test/perf/*.js"
},
"repository": {
"type": "git",
"url": "https://github.com/mweststrate/mobservable.git"
},
"author": "Michel Weststrate",
"license": "MIT",
"bugs": {
"url": "https://github.com/mweststrate/mobservable/issues"
},
"homepage": "https://mweststrate.github.io/mobservable",
"devDependencies": {
"babel": "^5.8.23",
"coveralls": "^2.11.4",
"istanbul": "^0.3.21",
"nodeunit": "^0.9.1",
"nodeunit-browser-tap": "^0.1.0",
"typescript": "^1.6.2",
"webpack": "^1.12.2"
},
"keywords": [
"mobservable",
"observable",
"react-component",
"react",
"reactjs",
"reactive",
"model",
"frp",
"functional-reactive-programming"
]
}

@@ -5,3 +5,3 @@ # mobservable

##### _Makes data observable. And functions reactive. Whut? Like Excel._
##### _Observable data. Reactive functions. Simple code._

@@ -13,3 +13,4 @@ [![Build Status](https://travis-ci.org/mweststrate/mobservable.svg?branch=master)](https://travis-ci.org/mweststrate/mobservable)

<br/>
New to Mobservable? Take the [five minute, interactive introduction](https://mweststrate.github.io/mobservable/getting-started.html)
* New to Mobservable? Take the [five minute, interactive introduction](https://mweststrate.github.io/mobservable/getting-started.html)
* [Official documentation](https://mweststrate.github.io/mobservable/)

@@ -19,5 +20,8 @@ ## Introduction

Mobservable enables your data structures to become observable.
Next to that it can make your functions reactive, so that they re-evaluate whenever relevant data is altered. This has major benefits for the simplicity, maintainability and performance of your code. This is the promise of Mobservable:
Next to that it can make your functions (or [React components](https://github.com/mweststrate/mobservable-react)) reactive, so that they re-evaluate whenever relevant data is altered.
It's like Excel for JavaScript: any data structure can be turned into a 'data cell', any function into a 'formula' that updates automatically.
This has major benefits for the simplicity, maintainability and performance of your code:
* Write complex applications which unmatched simple code.
* Enable unobtrusive state management: be free to use mutable objects, cyclic references, classes and real references to store state.
* Enable unopiniated state management: be free to use mutable objects, cyclic references, classes and real references to store state.
* Write declarative views that track their own dependencies. No subscriptions, cursors or other redundant declarations to manage.

@@ -50,32 +54,19 @@ * Build [high performing](mendix.com/tech-blog/making-react-reactive-pursuit-high-performing-easily-maintainable-react-apps/) React applications without Flux or Immutable data structures.

So what will this app do? It does nothing! The timer increases every second, but the will UI never update. To fix that, we should force the UI to refresh somehow upon each interval.
But that is the kind of dependency we should avoid in our code. We shouldn't have to _pull_ data from our state to update the UI. Instead, the data structures should be in control and call the UI when it needs an update. The state should be _pushed_ throughout our application. This is called inversion of control.
Without Mobservable, this app would do nothing beyond the initial render.
The timer would increase every second, but the would UI never update.
To fix that, your code should trigger the UI to update each time the `timerData` changes.
But there is a better way.
We shouldn't have to _pull_ data from our state to update the UI.
Instead, the data structures should be in control and call the UI whenever it becomes stale.
The state should be _pushed_ throughout our application.
We can apply two simple functions of Mobservable to achieve this.
In the example above this is achieved by making the `timerDate` observable and by turning the `Timer` component into an `observer`.
Mobservable will automatically track all relations between _observable data_ and _observing functions (or components)_ so that the minum amount of observers is updated to keep all observers fresh.
### mobservable.observable
The first function is `observable`. It is the swiss knife of mobservable and turns any data structure and function into its reactive counterpart. Objects, arrays, functions; they can all be made reactive. Reactiveness is contagious; new data that is put in reactive data will become reactive as well. To make our timer reactive, just change the first three lines of the code:
Its as simple as that. In the example above the `Timer` will automatically update each time the property `timerData.secondsPassed` is altered.
The actual interesting thing about this approach are the things that are *not* in the code:
```javascript
var timerData = mobservable.observable({
secondsPassed: 0
});
```
### mobservableReact.observer
The second important function is `observer` from the `mobservable-react` package. It turns a Reactjs component into a reactive one, that responds automatically to changes in data that is used by its render method. It can be used to wrap any react component, either created by using ES6 classes or `createClass`. So to fix the example, just update the timer definition to:
```javascript
var Timer = mobservableReact.observer(React.createClass{
/** Omitted */
}));
```
Its as simple as that. The `Timer` will now automatically update each time `timerData.secondsPassed` is altered.
The actual interesting thing about these changes are the things that are *not* in the code:
* The `setInterval` method didn't alter. It still treats `timerData` as a plain JS object.
* There is no state. Timer is still a dumb component.
* There is no state. Timer is a dumb component.
* There is no magic context being passed through components.

@@ -93,12 +84,5 @@ * There are no subscriptions of any kind that need to be managed.

* `npm install mobservable --save`.
* For React apps `npm install mobservable-react --save` as well. You might also be interested in the [dev tools for React and Mobservable](https://github.com/mweststrate/mobservable-react-devtools).
* For (Native) React apps `npm install mobservable-react --save` as well. You might also be interested in the [dev tools for React and Mobservable](https://github.com/mweststrate/mobservable-react-devtools).
* [Five minute interactive introducton to Mobservable and React](https://mweststrate.github.io/mobservable/getting-started.html)
## Resources
* [API documentation](https://mweststrate.github.io/mobservable/)
* [ES5, ES6, TypeScript syntax examples](https://github.com/mweststrate/mobservable/blob/master/docs/api.md)
* [TypeScript Typings](https://github.com/mweststrate/mobservable/blob/master/dist/mobservable.d.ts), also available through `tsd install mobservable --save`.
## Examples

@@ -127,16 +111,11 @@

**observable(value, options?)**
Turns a value into a reactive array, object, function, value or a reactive reference to a value.
The `observable` function is the swiss knife of mobservable and enriches any data structure or function with observable capabilities.
**autorun(function)**
Turns a function into an observer so that it will automatically be re-evaluated if any data values it uses changes.
**observer(reactJsComponent)**
Provided by the `mobservable-react` packaege, turns a ReactJS component into a reactive one, that automatically re-renders if any reactive data that it uses is changed.
The `observer` function (and ES6 decorator) from the `mobservable-react` turns any Reactjs component into a reactive one.
From there on it will responds automatically to any relevant change in _observable_ data that was used by its render method.
**extendObservable(target, properties)**
Extends an existing object with reactive properties.
**observe(function)**
Similar to `observable(function)`. Exception the created reactive function will not be lazy, so that it is executed even when it has no observers on its own.
Useful to bridge reactive code to imperative code.
## What others are saying...

@@ -143,0 +122,0 @@

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc