Socket
Socket
Sign inDemoInstall

mobx-utils

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mobx-utils - npm Package Compare versions

Comparing version 3.2.2 to 4.0.0-beta.2

lib/create-transformer.d.ts

2

CHANGELOG.md

@@ -37,3 +37,3 @@ # 3.2.2

mobx.useStrict(true) // don't allow state modifications outside actions
mobx.configure({ enforceActions: true }) // don't allow state modifications outside actions

@@ -40,0 +40,0 @@ class Store {

@@ -22,2 +22,1 @@ export declare function asyncAction(target: Object, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;

export declare function asyncAction<A1>(name: string, generator: (a1: A1) => IterableIterator<any>): (a1: A1) => Promise<any>;
export declare function createAsyncActionGenerator(name: string, generator: Function): () => Promise<{}>;

@@ -1,11 +0,3 @@

var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
import { action } from "mobx";
import { invariant } from "./utils";
import { flow } from "mobx";
import { deprecated } from "./utils";
/**

@@ -30,2 +22,4 @@ * `asyncAction` takes a generator function and automatically wraps all parts of the process in actions. See the examples below.

*
* N.B. due to a [babel limitation](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/issues/26), in Babel generatos cannot be combined with decorators. See also [#70](https://github.com/mobxjs/mobx-utils/issues/70)
*
* @example

@@ -50,3 +44,3 @@ * import {asyncAction} from "mobx-utils"

*
* mobx.useStrict(true) // don't allow state modifications outside actions
* mobx.configure({ enforceActions: true }) // don't allow state modifications outside actions
*

@@ -77,66 +71,4 @@ * class Store {

export function asyncAction(arg1, arg2) {
// decorator
if (typeof arguments[1] === "string") {
var name_1 = arguments[1];
var descriptor_1 = arguments[2];
if (descriptor_1 && descriptor_1.value) {
return Object.assign({}, descriptor_1, {
value: createAsyncActionGenerator(name_1, descriptor_1.value)
});
}
else {
return Object.assign({}, descriptor_1, {
set: function (v) {
Object.defineProperty(this, name_1, __assign({}, descriptor_1, { value: asyncAction(name_1, v) }));
}
});
}
}
// direct invocation
var generator = typeof arg1 === "string" ? arg2 : arg1;
var name = typeof arg1 === "string" ? arg1 : generator.name || "<unnamed async action>";
invariant(typeof generator === "function", "asyncAction expects function as first arg, got: " + generator);
return createAsyncActionGenerator(name, generator);
deprecated("asyncAction is deprecated. use mobx.flow instead");
return flow.apply(null, arguments);
}
var generatorId = 0;
export function createAsyncActionGenerator(name, generator) {
// Implementation based on https://github.com/tj/co/blob/master/index.js
return function () {
var ctx = this;
var args = arguments;
return new Promise(function (resolve, reject) {
var runId = ++generatorId;
var stepId = 0;
var gen = action(name + " - runid: " + runId + " - init", generator).apply(ctx, args);
onFulfilled(undefined); // kick off the process
function onFulfilled(res) {
var ret;
try {
ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.next).call(gen, res);
}
catch (e) {
return reject(e);
}
next(ret);
return null;
}
function onRejected(err) {
var ret;
try {
ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.throw).call(gen, err);
}
catch (e) {
return reject(e);
}
next(ret);
}
function next(ret) {
if (ret.done)
return resolve(ret.value);
// TODO: support more type of values? See https://github.com/tj/co/blob/249bbdc72da24ae44076afd716349d2089b31c4c/index.js#L100
invariant(ret.value && typeof ret.value.then === "function", "Only promises can be yielded to asyncAction, got: " + ret);
return ret.value.then(onFulfilled, onRejected);
}
});
};
}

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

import { isAction, autorun, autorunAsync, action, isObservableArray, runInAction } from "mobx";
import { isAction, autorun, action, isObservableArray, runInAction } from "mobx";
/**

@@ -50,5 +50,5 @@ * `chunkProcessor` takes an observable array, observes it and calls `processor`

if (debounce > 0)
return autorunAsync(runner, debounce);
return autorun(runner, { delay: debounce });
else
return autorun(runner);
}

@@ -7,3 +7,3 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

};
import { action, observable, isObservableObject, isObservableArray, isObservableMap, computed } from "mobx";
import { action, observable, isObservableObject, isObservableArray, isObservableMap, computed, keys } from "mobx";
import { invariant } from "./utils";

@@ -48,3 +48,3 @@ var RESERVED_NAMES = ["model", "reset", "submit", "isDirty", "isPropertyDirty"];

var _this = this;
this.localValues.keys().forEach(function (key) {
keys(this.localValues).forEach(function (key) {
var source = _this.localValues.get(key);

@@ -51,0 +51,0 @@ var destination = _this.model[key];

@@ -27,3 +27,3 @@ export declare type PromiseState = "pending" | "fulfilled" | "rejected";

/**
* `fromPromise` takes a Promise and returns an object with 3 observable properties that track
* `fromPromise` takes a Promise and returns a new Promise wrapping the original one. The returned Promise is also extended with 2 observable properties that track
* the status of the promise. The returned object has the following observable properties:

@@ -37,3 +37,3 @@ * - `value`: either the initial value, the value the Promise resolved to, or the value the Promise was rejected with. use `.state` if you need to be able to tell the difference.

*
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`.
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`. You may also use it with `await` in `async` functions.
*

@@ -40,0 +40,0 @@ * Note that the status strings are available as constants:

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

import { extendShallowObservable, action } from "mobx";
import { deprecated, invariant } from "./utils";
import { action, extendObservable } from "mobx";
import { invariant } from "./utils";
export var PENDING = "pending";

@@ -26,30 +26,20 @@ export var FULFILLED = "fulfilled";

}
var promise = new Promise(function (resolve, reject) {
origPromise.then(action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
resolve(value);
}), action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
reject(reason);
}));
});
var promise = origPromise;
origPromise.then(action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
}), action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
}));
promise.isPromiseBasedObservable = true;
promise.case = caseImpl;
extendShallowObservable(promise, {
extendObservable(promise, {
value: undefined,
state: PENDING
});
// TODO: remove in next major
Object.defineProperty(promise, "promise", {
get: function () {
deprecated("fromPromise().promise is deprecated. fromPromise now directly returns a promise");
return origPromise;
}
});
}, {}, { deep: false });
return promise;
}
/**
* `fromPromise` takes a Promise and returns an object with 3 observable properties that track
* `fromPromise` takes a Promise and returns a new Promise wrapping the original one. The returned Promise is also extended with 2 observable properties that track
* the status of the promise. The returned object has the following observable properties:

@@ -63,3 +53,3 @@ * - `value`: either the initial value, the value the Promise resolved to, or the value the Promise was rejected with. use `.state` if you need to be able to tell the difference.

*
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`.
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`. You may also use it with `await` in `async` functions.
*

@@ -66,0 +56,0 @@ * Note that the status strings are available as constants:

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

import { Atom, extras } from "mobx";
import { createAtom, _allowStateChanges } from "mobx";
import { NOOP, invariant } from "./utils";

@@ -79,7 +79,7 @@ /**

};
var atom = new Atom("ResourceBasedObservable", function () {
var atom = createAtom("ResourceBasedObservable", function () {
invariant(!isActive && !isDisposed);
isActive = true;
subscriber(function (newValue) {
extras.allowStateChanges(true, function () {
_allowStateChanges(true, function () {
value = newValue;

@@ -86,0 +86,0 @@ atom.reportChanged();

import { when } from "mobx";
import { deprecated } from "./utils";
/**

@@ -34,18 +35,7 @@ * Like normal `when`, except that this `when` will automatically dispose if the condition isn't met within a certain amount of time.

if (onTimeout === void 0) { onTimeout = function () { }; }
var done = false;
var handle = setTimeout(function () {
if (!done) {
disposer();
onTimeout();
}
}, timeout);
var disposer = when(expr, function () {
done = true;
clearTimeout(handle);
action();
deprecated("whenWithTimeout is deprecated, use mobx.when with timeout option instead");
return when(expr, action, {
timeout: timeout,
onError: onTimeout
});
return function () {
clearTimeout(handle);
disposer();
};
}

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

import { extras } from "mobx";
import { getAtom } from "mobx";
/**

@@ -31,3 +31,3 @@ * MobX normally suspends any computed value that is not in use by any reaction,

export function keepAlive(_1, _2) {
var computed = extras.getAtom(_1, _2);
var computed = getAtom(_1, _2);
if (!computed)

@@ -34,0 +34,0 @@ throw new Error("No computed provided, please provide an object created with `computed(() => expr)` or an object + property name");

@@ -39,2 +39,2 @@ export interface ILazyObservable<T> {

*/
export declare function lazyObservable<T>(fetch: (sink: (newValue: T) => void) => void, initialValue?: T, modifier?: (_: any) => any): ILazyObservable<T>;
export declare function lazyObservable<T>(fetch: (sink: (newValue: T) => void) => void, initialValue?: T): ILazyObservable<T>;

@@ -1,3 +0,2 @@

import { IDENTITY } from "./utils";
import { observable, extras, action } from "mobx";
import { observable, action, _allowStateChanges } from "mobx";
/**

@@ -36,7 +35,6 @@ * `lazyObservable` creates an observable around a `fetch` method that will not be invoked

*/
export function lazyObservable(fetch, initialValue, modifier) {
export function lazyObservable(fetch, initialValue) {
if (initialValue === void 0) { initialValue = undefined; }
if (modifier === void 0) { modifier = IDENTITY; }
var started = false;
var value = observable.shallowBox(modifier(initialValue));
var value = observable.box(initialValue, { deep: false });
var currentFnc = function () {

@@ -46,3 +44,3 @@ if (!started) {

fetch(function (newValue) {
extras.allowStateChanges(true, function () {
_allowStateChanges(true, function () {
value.set(newValue);

@@ -49,0 +47,0 @@ });

@@ -14,1 +14,3 @@ export * from "./from-promise";

export * from "./when-async";
export * from "./expr";
export * from "./create-transformer";

@@ -14,1 +14,3 @@ export * from "./from-promise";

export * from "./when-async";
export * from "./expr";
export * from "./create-transformer";

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

import { extras } from "mobx";
import { _isComputingDerivation } from "mobx";
import { fromResource } from "./from-resource";

@@ -32,3 +32,3 @@ var tickers = {};

if (interval === void 0) { interval = 1000; }
if (!extras.isComputingDerivation()) {
if (!_isComputingDerivation()) {
// See #40

@@ -35,0 +35,0 @@ return Date.now();

@@ -87,9 +87,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

__decorate([
action
action.bound
], StreamListener.prototype, "next", null);
__decorate([
action
action.bound
], StreamListener.prototype, "complete", null);
__decorate([
action
action.bound
], StreamListener.prototype, "error", null);

@@ -96,0 +96,0 @@ return StreamListener;

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

import { isAction, autorun, autorunAsync, action, isObservableArray, runInAction } from "mobx";
import { isAction, autorun, action, isObservableArray, runInAction } from "mobx";
/**

@@ -36,5 +36,5 @@ * `queueProcessor` takes an observable array, observes it and calls `processor`

if (debounce > 0)
return autorunAsync(runner, debounce);
return autorun(runner, { delay: debounce });
else
return autorun(runner);
}

@@ -6,1 +6,2 @@ export declare type IDisposer = () => void;

export declare function deprecated(msg: string): void;
export declare function addHiddenProp(object: any, propName: string, value: any): void;

@@ -15,1 +15,9 @@ export var NOOP = function () { };

}
export function addHiddenProp(object, propName, value) {
Object.defineProperty(object, propName, {
enumerable: false,
writable: true,
configurable: true,
value: value
});
}
import { when } from "mobx";
import { deprecated } from "./utils";
/**

@@ -15,15 +16,6 @@ * Like normal `when`, except that this `when` will return a promise that resolves when the expression becomes truthy

if (timeout === void 0) { timeout = 0; }
return new Promise(function (resolve, reject) {
var timeoutHandle;
var disposer = when(fn, function () {
if (timeout > 0)
clearTimeout(timeoutHandle);
resolve();
});
if (timeout > 0)
setTimeout(function () {
disposer();
reject(new Error("TIMEOUT"));
}, timeout);
deprecated("whenAsync is deprecated, use mobx.when without effect instead");
return when(fn, {
timeout: timeout
});
}

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

import { Atom, action, autorun, autorunAsync, computed, extendShallowObservable, extras, isAction, isObservableArray, isObservableMap, isObservableObject, observable, runInAction, when } from 'mobx';
import { _allowStateChanges, _isComputingDerivation, action, autorun, computed, createAtom, extendObservable, flow, getAtom, isAction, isObservableArray, isObservableMap, isObservableObject, keys, observable, onBecomeUnobserved, runInAction, when } from 'mobx';

@@ -17,2 +17,10 @@ var NOOP = function () { };

}
function addHiddenProp(object, propName, value) {
Object.defineProperty(object, propName, {
enumerable: false,
writable: true,
configurable: true,
value: value
});
}

@@ -42,30 +50,20 @@ var PENDING = "pending";

}
var promise = new Promise(function (resolve, reject) {
origPromise.then(action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
resolve(value);
}), action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
reject(reason);
}));
});
var promise = origPromise;
origPromise.then(action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
}), action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
}));
promise.isPromiseBasedObservable = true;
promise.case = caseImpl;
extendShallowObservable(promise, {
extendObservable(promise, {
value: undefined,
state: PENDING
});
// TODO: remove in next major
Object.defineProperty(promise, "promise", {
get: function () {
deprecated("fromPromise().promise is deprecated. fromPromise now directly returns a promise");
return origPromise;
}
});
}, {}, { deep: false });
return promise;
}
/**
* `fromPromise` takes a Promise and returns an object with 3 observable properties that track
* `fromPromise` takes a Promise and returns a new Promise wrapping the original one. The returned Promise is also extended with 2 observable properties that track
* the status of the promise. The returned object has the following observable properties:

@@ -79,3 +77,3 @@ * - `value`: either the initial value, the value the Promise resolved to, or the value the Promise was rejected with. use `.state` if you need to be able to tell the difference.

*
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`.
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`. You may also use it with `await` in `async` functions.
*

@@ -189,7 +187,6 @@ * Note that the status strings are available as constants:

*/
function lazyObservable(fetch, initialValue, modifier) {
function lazyObservable(fetch, initialValue) {
if (initialValue === void 0) { initialValue = undefined; }
if (modifier === void 0) { modifier = IDENTITY; }
var started = false;
var value = observable.shallowBox(modifier(initialValue));
var value = observable.box(initialValue, { deep: false });
var currentFnc = function () {

@@ -199,3 +196,3 @@ if (!started) {

fetch(function (newValue) {
extras.allowStateChanges(true, function () {
_allowStateChanges(true, function () {
value.set(newValue);

@@ -304,7 +301,7 @@ });

};
var atom = new Atom("ResourceBasedObservable", function () {
var atom = createAtom("ResourceBasedObservable", function () {
invariant(!isActive && !isDisposed);
isActive = true;
subscriber(function (newValue) {
extras.allowStateChanges(true, function () {
_allowStateChanges(true, function () {
value = newValue;

@@ -416,9 +413,9 @@ atom.reportChanged();

__decorate([
action
action.bound
], StreamListener.prototype, "next", null);
__decorate([
action
action.bound
], StreamListener.prototype, "complete", null);
__decorate([
action
action.bound
], StreamListener.prototype, "error", null);

@@ -501,3 +498,3 @@ return StreamListener;

var _this = this;
this.localValues.keys().forEach(function (key) {
keys(this.localValues).forEach(function (key) {
var source = _this.localValues.get(key);

@@ -618,18 +615,7 @@ var destination = _this.model[key];

if (onTimeout === void 0) { onTimeout = function () { }; }
var done = false;
var handle = setTimeout(function () {
if (!done) {
disposer();
onTimeout();
}
}, timeout);
var disposer = when(expr, function () {
done = true;
clearTimeout(handle);
action$$1();
deprecated("whenWithTimeout is deprecated, use mobx.when with timeout option instead");
return when(expr, action$$1, {
timeout: timeout,
onError: onTimeout
});
return function () {
clearTimeout(handle);
disposer();
};
}

@@ -666,3 +652,3 @@

function keepAlive(_1, _2) {
var computed$$1 = extras.getAtom(_1, _2);
var computed$$1 = getAtom(_1, _2);
if (!computed$$1)

@@ -707,3 +693,3 @@ throw new Error("No computed provided, please provide an object created with `computed(() => expr)` or an object + property name");

if (debounce > 0)
return autorunAsync(runner, debounce);
return autorun(runner, { delay: debounce });
else

@@ -761,3 +747,3 @@ return autorun(runner);

if (debounce > 0)
return autorunAsync(runner, debounce);
return autorun(runner, { delay: debounce });
else

@@ -796,3 +782,3 @@ return autorun(runner);

if (interval === void 0) { interval = 1000; }
if (!extras.isComputingDerivation()) {
if (!_isComputingDerivation()) {
// See #40

@@ -831,10 +817,2 @@ return Date.now();

var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
/**

@@ -859,2 +837,4 @@ * `asyncAction` takes a generator function and automatically wraps all parts of the process in actions. See the examples below.

*
* N.B. due to a [babel limitation](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/issues/26), in Babel generatos cannot be combined with decorators. See also [#70](https://github.com/mobxjs/mobx-utils/issues/70)
*
* @example

@@ -879,3 +859,3 @@ * import {asyncAction} from "mobx-utils"

*
* mobx.useStrict(true) // don't allow state modifications outside actions
* mobx.configure({ enforceActions: true }) // don't allow state modifications outside actions
*

@@ -906,67 +886,5 @@ * class Store {

function asyncAction(arg1, arg2) {
// decorator
if (typeof arguments[1] === "string") {
var name_1 = arguments[1];
var descriptor_1 = arguments[2];
if (descriptor_1 && descriptor_1.value) {
return Object.assign({}, descriptor_1, {
value: createAsyncActionGenerator(name_1, descriptor_1.value)
});
}
else {
return Object.assign({}, descriptor_1, {
set: function (v) {
Object.defineProperty(this, name_1, __assign({}, descriptor_1, { value: asyncAction(name_1, v) }));
}
});
}
}
// direct invocation
var generator = typeof arg1 === "string" ? arg2 : arg1;
var name = typeof arg1 === "string" ? arg1 : generator.name || "<unnamed async action>";
invariant(typeof generator === "function", "asyncAction expects function as first arg, got: " + generator);
return createAsyncActionGenerator(name, generator);
deprecated("asyncAction is deprecated. use mobx.flow instead");
return flow.apply(null, arguments);
}
var generatorId = 0;
function createAsyncActionGenerator(name, generator) {
// Implementation based on https://github.com/tj/co/blob/master/index.js
return function () {
var ctx = this;
var args = arguments;
return new Promise(function (resolve, reject) {
var runId = ++generatorId;
var stepId = 0;
var gen = action(name + " - runid: " + runId + " - init", generator).apply(ctx, args);
onFulfilled(undefined); // kick off the process
function onFulfilled(res) {
var ret;
try {
ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.next).call(gen, res);
}
catch (e) {
return reject(e);
}
next(ret);
return null;
}
function onRejected(err) {
var ret;
try {
ret = action(name + " - runid: " + runId + " - yield " + stepId++, gen.throw).call(gen, err);
}
catch (e) {
return reject(e);
}
next(ret);
}
function next(ret) {
if (ret.done)
return resolve(ret.value);
// TODO: support more type of values? See https://github.com/tj/co/blob/249bbdc72da24ae44076afd716349d2089b31c4c/index.js#L100
invariant(ret.value && typeof ret.value.then === "function", "Only promises can be yielded to asyncAction, got: " + ret);
return ret.value.then(onFulfilled, onRejected);
}
});
};
}

@@ -986,17 +904,79 @@ /**

if (timeout === void 0) { timeout = 0; }
return new Promise(function (resolve, reject) {
var timeoutHandle;
var disposer = when(fn, function () {
if (timeout > 0)
clearTimeout(timeoutHandle);
resolve();
});
if (timeout > 0)
setTimeout(function () {
disposer();
reject(new Error("TIMEOUT"));
}, timeout);
deprecated("whenAsync is deprecated, use mobx.when without effect instead");
return when(fn, {
timeout: timeout
});
}
export { PENDING, FULFILLED, REJECTED, fromPromise, isPromiseBasedObservable, lazyObservable, fromResource, toStream, fromStream, createViewModel, whenWithTimeout, keepAlive, queueProcessor, chunkProcessor, now, NOOP, IDENTITY, invariant, deprecated, asyncAction, createAsyncActionGenerator, whenAsync };
/**
* expr can be used to create temporarily views inside views.
* This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
*
* In the following example the expression prevents that a component is rerender _each time_ the selection changes;
* instead it will only rerenders when the current todo is (de)selected.
*
* @example
* const Todo = observer((props) => {
* const todo = props.todo;
* const isSelected = mobxUtils.expr(() => props.viewState.selection === todo);
* return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
* });
*
*/
function expr(expr) {
if (!_isComputingDerivation())
console.warn("'expr' should only be used inside other reactive functions.");
// optimization: would be more efficient if the expr itself wouldn't be evaluated first on the next change, but just a 'changed' signal would be fired
return computed(expr).get();
}
var memoizationId = 0;
/**
* Creates a function that maps an object to a view.
* The mapping is memoized.
*
* See: https://mobx.js.org/refguide/create-transformer.html
*/
function createTransformer(transformer, onCleanup) {
invariant(typeof transformer === "function" && transformer.length < 2, "createTransformer expects a function that accepts one argument");
// Memoizes: object id -> reactive view that applies transformer to the object
var views = {};
function createView(sourceIdentifier, sourceObject) {
var latestValue;
var expr = computed(function () {
return (latestValue = transformer(sourceObject));
}, {
name: "Transformer-" + transformer.name + "-" + sourceIdentifier
});
var disposer = onBecomeUnobserved(expr, function () {
delete views[sourceIdentifier];
disposer();
if (onCleanup)
onCleanup(latestValue, sourceObject);
});
return expr;
}
return function (object) {
var identifier = getMemoizationId(object);
var reactiveView = views[identifier];
if (reactiveView)
return reactiveView.get();
// Not in cache; create a reactive view
reactiveView = views[identifier] = createView(identifier, object);
return reactiveView.get();
};
}
function getMemoizationId(object) {
if (typeof object === "string" || typeof object === "number")
return object;
if (object === null || typeof object !== "object")
throw new Error("[mobx-utils] transform expected an object, string or number, got: " + object);
var tid = object.$transformId;
if (tid === undefined) {
tid = ++memoizationId;
addHiddenProp(object, "$transformId", tid);
}
return tid;
}
export { PENDING, FULFILLED, REJECTED, fromPromise, isPromiseBasedObservable, lazyObservable, fromResource, toStream, fromStream, createViewModel, whenWithTimeout, keepAlive, queueProcessor, chunkProcessor, now, NOOP, IDENTITY, invariant, deprecated, addHiddenProp, asyncAction, whenAsync, expr, createTransformer };

@@ -21,2 +21,10 @@ (function (global, factory) {

}
function addHiddenProp(object, propName, value) {
Object.defineProperty(object, propName, {
enumerable: false,
writable: true,
configurable: true,
value: value
});
}

@@ -46,30 +54,20 @@ var PENDING = "pending";

}
var promise = new Promise(function (resolve, reject) {
origPromise.then(mobx.action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
resolve(value);
}), mobx.action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
reject(reason);
}));
});
var promise = origPromise;
origPromise.then(mobx.action("observableFromPromise-resolve", function (value) {
promise.value = value;
promise.state = FULFILLED;
}), mobx.action("observableFromPromise-reject", function (reason) {
promise.value = reason;
promise.state = REJECTED;
}));
promise.isPromiseBasedObservable = true;
promise.case = caseImpl;
mobx.extendShallowObservable(promise, {
mobx.extendObservable(promise, {
value: undefined,
state: PENDING
});
// TODO: remove in next major
Object.defineProperty(promise, "promise", {
get: function () {
deprecated("fromPromise().promise is deprecated. fromPromise now directly returns a promise");
return origPromise;
}
});
}, {}, { deep: false });
return promise;
}
/**
* `fromPromise` takes a Promise and returns an object with 3 observable properties that track
* `fromPromise` takes a Promise and returns a new Promise wrapping the original one. The returned Promise is also extended with 2 observable properties that track
* the status of the promise. The returned object has the following observable properties:

@@ -83,3 +81,3 @@ * - `value`: either the initial value, the value the Promise resolved to, or the value the Promise was rejected with. use `.state` if you need to be able to tell the difference.

*
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`.
* The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`. You may also use it with `await` in `async` functions.
*

@@ -193,7 +191,6 @@ * Note that the status strings are available as constants:

*/
function lazyObservable(fetch, initialValue, modifier) {
function lazyObservable(fetch, initialValue) {
if (initialValue === void 0) { initialValue = undefined; }
if (modifier === void 0) { modifier = IDENTITY; }
var started = false;
var value = mobx.observable.shallowBox(modifier(initialValue));
var value = mobx.observable.box(initialValue, { deep: false });
var currentFnc = function () {

@@ -203,3 +200,3 @@ if (!started) {

fetch(function (newValue) {
mobx.extras.allowStateChanges(true, function () {
mobx._allowStateChanges(true, function () {
value.set(newValue);

@@ -308,7 +305,7 @@ });

};
var atom = new mobx.Atom("ResourceBasedObservable", function () {
var atom = mobx.createAtom("ResourceBasedObservable", function () {
invariant(!isActive && !isDisposed);
isActive = true;
subscriber(function (newValue) {
mobx.extras.allowStateChanges(true, function () {
mobx._allowStateChanges(true, function () {
value = newValue;

@@ -420,9 +417,9 @@ atom.reportChanged();

__decorate([
mobx.action
mobx.action.bound
], StreamListener.prototype, "next", null);
__decorate([
mobx.action
mobx.action.bound
], StreamListener.prototype, "complete", null);
__decorate([
mobx.action
mobx.action.bound
], StreamListener.prototype, "error", null);

@@ -505,3 +502,3 @@ return StreamListener;

var _this = this;
this.localValues.keys().forEach(function (key) {
mobx.keys(this.localValues).forEach(function (key) {
var source = _this.localValues.get(key);

@@ -622,18 +619,7 @@ var destination = _this.model[key];

if (onTimeout === void 0) { onTimeout = function () { }; }
var done = false;
var handle = setTimeout(function () {
if (!done) {
disposer();
onTimeout();
}
}, timeout);
var disposer = mobx.when(expr, function () {
done = true;
clearTimeout(handle);
action$$1();
deprecated("whenWithTimeout is deprecated, use mobx.when with timeout option instead");
return mobx.when(expr, action$$1, {
timeout: timeout,
onError: onTimeout
});
return function () {
clearTimeout(handle);
disposer();
};
}

@@ -670,3 +656,3 @@

function keepAlive(_1, _2) {
var computed$$1 = mobx.extras.getAtom(_1, _2);
var computed$$1 = mobx.getAtom(_1, _2);
if (!computed$$1)

@@ -711,3 +697,3 @@ throw new Error("No computed provided, please provide an object created with `computed(() => expr)` or an object + property name");

if (debounce > 0)
return mobx.autorunAsync(runner, debounce);
return mobx.autorun(runner, { delay: debounce });
else

@@ -765,3 +751,3 @@ return mobx.autorun(runner);

if (debounce > 0)
return mobx.autorunAsync(runner, debounce);
return mobx.autorun(runner, { delay: debounce });
else

@@ -800,3 +786,3 @@ return mobx.autorun(runner);

if (interval === void 0) { interval = 1000; }
if (!mobx.extras.isComputingDerivation()) {
if (!mobx._isComputingDerivation()) {
// See #40

@@ -835,10 +821,2 @@ return Date.now();

var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
/**

@@ -863,2 +841,4 @@ * `asyncAction` takes a generator function and automatically wraps all parts of the process in actions. See the examples below.

*
* N.B. due to a [babel limitation](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/issues/26), in Babel generatos cannot be combined with decorators. See also [#70](https://github.com/mobxjs/mobx-utils/issues/70)
*
* @example

@@ -883,3 +863,3 @@ * import {asyncAction} from "mobx-utils"

*
* mobx.useStrict(true) // don't allow state modifications outside actions
* mobx.configure({ enforceActions: true }) // don't allow state modifications outside actions
*

@@ -910,67 +890,5 @@ * class Store {

function asyncAction(arg1, arg2) {
// decorator
if (typeof arguments[1] === "string") {
var name_1 = arguments[1];
var descriptor_1 = arguments[2];
if (descriptor_1 && descriptor_1.value) {
return Object.assign({}, descriptor_1, {
value: createAsyncActionGenerator(name_1, descriptor_1.value)
});
}
else {
return Object.assign({}, descriptor_1, {
set: function (v) {
Object.defineProperty(this, name_1, __assign({}, descriptor_1, { value: asyncAction(name_1, v) }));
}
});
}
}
// direct invocation
var generator = typeof arg1 === "string" ? arg2 : arg1;
var name = typeof arg1 === "string" ? arg1 : generator.name || "<unnamed async action>";
invariant(typeof generator === "function", "asyncAction expects function as first arg, got: " + generator);
return createAsyncActionGenerator(name, generator);
deprecated("asyncAction is deprecated. use mobx.flow instead");
return mobx.flow.apply(null, arguments);
}
var generatorId = 0;
function createAsyncActionGenerator(name, generator) {
// Implementation based on https://github.com/tj/co/blob/master/index.js
return function () {
var ctx = this;
var args = arguments;
return new Promise(function (resolve, reject) {
var runId = ++generatorId;
var stepId = 0;
var gen = mobx.action(name + " - runid: " + runId + " - init", generator).apply(ctx, args);
onFulfilled(undefined); // kick off the process
function onFulfilled(res) {
var ret;
try {
ret = mobx.action(name + " - runid: " + runId + " - yield " + stepId++, gen.next).call(gen, res);
}
catch (e) {
return reject(e);
}
next(ret);
return null;
}
function onRejected(err) {
var ret;
try {
ret = mobx.action(name + " - runid: " + runId + " - yield " + stepId++, gen.throw).call(gen, err);
}
catch (e) {
return reject(e);
}
next(ret);
}
function next(ret) {
if (ret.done)
return resolve(ret.value);
// TODO: support more type of values? See https://github.com/tj/co/blob/249bbdc72da24ae44076afd716349d2089b31c4c/index.js#L100
invariant(ret.value && typeof ret.value.then === "function", "Only promises can be yielded to asyncAction, got: " + ret);
return ret.value.then(onFulfilled, onRejected);
}
});
};
}

@@ -990,17 +908,79 @@ /**

if (timeout === void 0) { timeout = 0; }
return new Promise(function (resolve, reject) {
var timeoutHandle;
var disposer = mobx.when(fn, function () {
if (timeout > 0)
clearTimeout(timeoutHandle);
resolve();
});
if (timeout > 0)
setTimeout(function () {
disposer();
reject(new Error("TIMEOUT"));
}, timeout);
deprecated("whenAsync is deprecated, use mobx.when without effect instead");
return mobx.when(fn, {
timeout: timeout
});
}
/**
* expr can be used to create temporarily views inside views.
* This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
*
* In the following example the expression prevents that a component is rerender _each time_ the selection changes;
* instead it will only rerenders when the current todo is (de)selected.
*
* @example
* const Todo = observer((props) => {
* const todo = props.todo;
* const isSelected = mobxUtils.expr(() => props.viewState.selection === todo);
* return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
* });
*
*/
function expr(expr) {
if (!mobx._isComputingDerivation())
console.warn("'expr' should only be used inside other reactive functions.");
// optimization: would be more efficient if the expr itself wouldn't be evaluated first on the next change, but just a 'changed' signal would be fired
return mobx.computed(expr).get();
}
var memoizationId = 0;
/**
* Creates a function that maps an object to a view.
* The mapping is memoized.
*
* See: https://mobx.js.org/refguide/create-transformer.html
*/
function createTransformer(transformer, onCleanup) {
invariant(typeof transformer === "function" && transformer.length < 2, "createTransformer expects a function that accepts one argument");
// Memoizes: object id -> reactive view that applies transformer to the object
var views = {};
function createView(sourceIdentifier, sourceObject) {
var latestValue;
var expr = mobx.computed(function () {
return (latestValue = transformer(sourceObject));
}, {
name: "Transformer-" + transformer.name + "-" + sourceIdentifier
});
var disposer = mobx.onBecomeUnobserved(expr, function () {
delete views[sourceIdentifier];
disposer();
if (onCleanup)
onCleanup(latestValue, sourceObject);
});
return expr;
}
return function (object) {
var identifier = getMemoizationId(object);
var reactiveView = views[identifier];
if (reactiveView)
return reactiveView.get();
// Not in cache; create a reactive view
reactiveView = views[identifier] = createView(identifier, object);
return reactiveView.get();
};
}
function getMemoizationId(object) {
if (typeof object === "string" || typeof object === "number")
return object;
if (object === null || typeof object !== "object")
throw new Error("[mobx-utils] transform expected an object, string or number, got: " + object);
var tid = object.$transformId;
if (tid === undefined) {
tid = ++memoizationId;
addHiddenProp(object, "$transformId", tid);
}
return tid;
}
exports.PENDING = PENDING;

@@ -1025,5 +1005,7 @@ exports.FULFILLED = FULFILLED;

exports.deprecated = deprecated;
exports.addHiddenProp = addHiddenProp;
exports.asyncAction = asyncAction;
exports.createAsyncActionGenerator = createAsyncActionGenerator;
exports.whenAsync = whenAsync;
exports.expr = expr;
exports.createTransformer = createTransformer;

@@ -1030,0 +1012,0 @@ Object.defineProperty(exports, '__esModule', { value: true });

{
"name": "mobx-utils",
"version": "3.2.2",
"version": "4.0.0-beta.2",
"description": "Utility functions and common patterns for MobX",

@@ -13,3 +13,4 @@ "main": "mobx-utils.umd.js",

"build": "tsc -p src && rollup lib/mobx-utils.js -e mobx -g mobx:mobx -o mobx-utils.umd.js -f umd --name mobxUtils && rollup lib/mobx-utils.js -e mobx -o mobx-utils.module.js -f es",
"test": "npm run build && tsc -p test && tape test/*.js .test-ts/*.js | faucet",
"watch": "yarn jest --watch",
"test": "yarn jest",
"lint:js": "eslint ./test",

@@ -19,3 +20,3 @@ "lint:ts": "tslint ./src/*.ts",

"prepublish": "npm run build && npm run build-docs",
"coverage": "npm run build && tsc -p test && istanbul cover tape test/*.js .test-ts/*.js && cat ./coverage/lcov.info|coveralls",
"coverage": "yarn jest --coverage",
"build-docs": "npm run build && documentation readme lib/mobx-utils.js --section API"

@@ -38,2 +39,3 @@ },

"devDependencies": {
"@types/jest": "^22.2.0",
"@types/tape": "^4.2.30",

@@ -45,9 +47,10 @@ "babel-eslint": "^7.1.0",

"faucet": "0.0.1",
"istanbul": "^0.3.21",
"jest": "^22.4.2",
"lint-staged": "^4.2.3",
"mobx": "^3.0.0",
"lodash.intersection": "^4.4.0",
"mobx": "^4.0.0-beta.1",
"prettier": "^1.7.2",
"rollup": "^0.50.0",
"rxjs": "^5.0.2",
"tape": "^4.2.2",
"ts-jest": "^22.4.1",
"tslint": "^3.15.1",

@@ -59,3 +62,3 @@ "tslint-eslint-rules": "^2.1.0",

"peerDependencies": {
"mobx": "^3.0.0"
"mobx": "4.0.0-beta.2"
},

@@ -70,3 +73,25 @@ "keywords": [

"state management"
]
}
],
"jest": {
"transform": {
"^.+\\.ts?$": "ts-jest"
},
"testRegex": "test/.*\\.(t|j)sx?$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json"
],
"testPathIgnorePatterns": [
"/node_modules/",
"/lib/",
"/coverage/",
"/\\./"
],
"watchPathIgnorePatterns": [
"<rootDir>/node_modules/"
]
}
}

@@ -27,3 +27,3 @@ # MobX-utils

`fromPromise` takes a Promise and returns an object with 3 observable properties that track
`fromPromise` takes a Promise and returns a new Promise wrapping the original one. The returned Promise is also extended with 2 observable properties that track
the status of the promise. The returned object has the following observable properties:

@@ -39,3 +39,3 @@

The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`.
The returned object implements `PromiseLike<TValue>`, so you can chain additional `Promise` handlers using `then`. You may also use it with `await` in `async` functions.

@@ -124,3 +124,2 @@ Note that the status strings are available as constants:

- `initialValue` **T** optional initialValue that will be returned from `current` as long as the `sink` has not been called at least once (optional, default `undefined`)
- `modifier`

@@ -499,2 +498,4 @@ **Examples**

N.B. due to a [babel limitation](https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/issues/26), in Babel generatos cannot be combined with decorators. See also [#70](https://github.com/mobxjs/mobx-utils/issues/70)
**Parameters**

@@ -527,3 +528,3 @@

mobx.useStrict(true) // don't allow state modifications outside actions
mobx.configure({ enforceActions: true }) // don't allow state modifications outside actions

@@ -569,1 +570,35 @@ class Store {

Returns **any** Promise for when an observable eventually matches some condition. Rejects if timeout is provided and has expired
## expr
expr can be used to create temporarily views inside views.
This can be improved to improve performance if a value changes often, but usually doesn't affect the outcome of an expression.
In the following example the expression prevents that a component is rerender _each time_ the selection changes;
instead it will only rerenders when the current todo is (de)selected.
**Parameters**
- `expr`
**Examples**
```javascript
const Todo = observer((props) => {
const todo = props.todo;
const isSelected = mobxUtils.expr(() => props.viewState.selection === todo);
return <div className={isSelected ? "todo todo-selected" : "todo"}>{todo.title}</div>
});
```
## createTransformer
Creates a function that maps an object to a view.
The mapping is memoized.
See: <https://mobx.js.org/refguide/create-transformer.html>
**Parameters**
- `transformer`
- `onCleanup`
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