Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract messages to separate file #GoodnessSquad #783

Merged
merged 9 commits into from
Jan 26, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/api/action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {invariant, addHiddenProp} from "../utils/utils";
import {createClassPropertyDecorator} from "../utils/decorators";
import {createAction, executeAction} from "../core/action";
import {getMessage} from "../utils/messages";


export interface IActionFactory {
// nameless actions
Expand Down Expand Up @@ -51,7 +53,7 @@ const actionFieldDecorator = createClassPropertyDecorator(
return this[key];
},
function () {
invariant(false, "It is not allowed to assign new values to @action fields");
invariant(false, getMessage("m001"));
},
false,
true
Expand All @@ -65,7 +67,7 @@ const boundActionDecorator = createClassPropertyDecorator(
return this[key];
},
function () {
invariant(false, "It is not allowed to assign new values to @action fields");
invariant(false, getMessage("m001"));
},
false,
false
Expand Down Expand Up @@ -115,8 +117,8 @@ export function runInAction<T>(arg1, arg2?, arg3?) {
const fn = typeof arg1 === "function" ? arg1 : arg2;
const scope = typeof arg1 === "function" ? arg2 : arg3;

invariant(typeof fn === "function", "`runInAction` expects a function");
invariant(fn.length === 0, "`runInAction` expects a function without arguments");
invariant(typeof fn === "function", getMessage("m002"));
invariant(fn.length === 0, getMessage("m003"));
invariant(typeof actionName === "string" && actionName.length > 0, `actions should have valid names, got: '${actionName}'`);

return executeAction(actionName, fn, scope, undefined);
Expand Down
11 changes: 6 additions & 5 deletions src/api/autorun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {isModifierDescriptor} from "../types/modifiers";
import {Reaction, IReactionPublic, IReactionDisposer} from "../core/reaction";
import {untrackedStart, untrackedEnd} from "../core/derivation";
import {action, isAction} from "../api/action";
import {getMessage} from "../utils/messages";

/**
* Creates a reactive view and keeps it alive, so that the view is always
Expand Down Expand Up @@ -37,10 +38,10 @@ export function autorun(arg1: any, arg2: any, arg3?: any) {
scope = arg2;
}

invariant(typeof view === "function", "autorun expects a function");
invariant(typeof view === "function", getMessage("m004"));
invariant(
isAction(view) === false,
"Warning: attempted to pass an action to autorun. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action."
getMessage("m005")
);
if (scope)
view = view.bind(scope);
Expand Down Expand Up @@ -121,7 +122,7 @@ export function autorunAsync(arg1: any, arg2: any, arg3?: any, arg4?: any) {
}
invariant(
isAction(func) === false,
"Warning: attempted to pass an action to autorunAsync. Actions are untracked and will not trigger on state changes. Use `reaction` or wrap only your state modification code in an action."
getMessage("m006")
);
if (delay === void 0)
delay = 1;
Expand Down Expand Up @@ -169,10 +170,10 @@ export function reaction<T>(expression: (r: IReactionPublic) => T, effect: (arg:
export function reaction<T>(expression: (r: IReactionPublic) => T, effect: (arg: T, r: IReactionPublic) => void, fireImmediately?: boolean): IReactionDisposer;
export function reaction<T>(expression: (r: IReactionPublic) => T, effect: (arg: T, r: IReactionPublic) => void, arg3: any) {
if (arguments.length > 3) {
fail("reaction only accepts 2 or 3 arguments. If migrating from MobX 2, please provide an options object");
fail(getMessage("m007"));
}
if (isModifierDescriptor(expression)) {
fail("wrapping reaction expression in `asReference` is no longer supported, use options object instead");
fail(getMessage("m008"));
}

let opts: IReactionOptions;
Expand Down
10 changes: 5 additions & 5 deletions src/api/computed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {asObservableObject, defineComputedProperty} from "../types/observableobj
import {invariant} from "../utils/utils";
import {createClassPropertyDecorator} from "../utils/decorators";
import {ComputedValue, IComputedValue} from "../core/computedvalue";

import {getMessage} from "../utils/messages";

export interface IComputedValueOptions<T> {
compareStructural?: boolean;
Expand All @@ -23,8 +23,8 @@ export interface IComputed {
function createComputedDecorator(compareStructural) {
return createClassPropertyDecorator(
(target, name, _, __, originalDescriptor) => {
invariant(typeof originalDescriptor !== "undefined", "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'. It looks like it was used on a property.");
invariant(typeof originalDescriptor.get === "function", "@computed can only be used on getter functions, like: '@computed get myProps() { return ...; }'");
invariant(typeof originalDescriptor !== "undefined", getMessage("m009"));
invariant(typeof originalDescriptor.get === "function", getMessage("m010"));

const adm = asObservableObject(target, "");
defineComputedProperty(adm, name, originalDescriptor.get, originalDescriptor.set, compareStructural, false);
Expand Down Expand Up @@ -55,8 +55,8 @@ export var computed: IComputed = (
if (typeof arg2 === "string") {
return computedDecorator.apply(null, arguments);
}
invariant(typeof arg1 === "function", "First argument to `computed` should be an expression. If using computed as decorator, don't pass it arguments");
invariant(arguments.length < 3, "computed takes one or two arguments if used as function");
invariant(typeof arg1 === "function", getMessage("m011"));
invariant(arguments.length < 3, getMessage("m012"));
const opts: IComputedValueOptions<any> = typeof arg2 === "object" ? arg2 : {};
opts.setter = typeof arg2 === "function" ? arg2 : opts.setter;
return new ComputedValue(arg1, opts.context, opts.compareStructural || opts.struct || false, opts.name || arg1.name || "", opts.setter);
Expand Down
3 changes: 2 additions & 1 deletion src/api/expr.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {computed} from "../api/computed";
import {isComputingDerivation} from "../core/derivation";
import {getMessage} from "../utils/messages";

/**
* expr can be used to create temporarily views inside views.
Expand All @@ -17,7 +18,7 @@ import {isComputingDerivation} from "../core/derivation";
*/
export function expr<T>(expr: () => T, scope?): T {
if (!isComputingDerivation())
console.warn("[mobx.expr] 'expr' should only be used inside other reactive functions.");
console.warn(getMessage("m013"));
// 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, { context: scope }).get();
}
12 changes: 7 additions & 5 deletions src/api/extendobservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {asObservableObject, defineObservablePropertyFromDescriptor} from "../typ
import {isObservable} from "../api/isobservable";
import {invariant, isPropertyConfigurable, hasOwnProperty} from "../utils/utils";
import {deepEnhancer, referenceEnhancer, IEnhancer} from "../types/modifiers";
import {getMessage} from "../utils/messages";


export function extendObservable<A extends Object, B extends Object>(target: A, ...properties: B[]): A & B {
return extendObservableHelper(target, deepEnhancer, properties) as any;
Expand All @@ -13,13 +15,13 @@ export function extendShallowObservable<A extends Object, B extends Object>(targ
}

export function extendObservableHelper(target: Object, defaultEnhancer: IEnhancer<any>, properties: Object[]): Object {
invariant(arguments.length >= 2, "extendObservable expected 2 or more arguments");
invariant(typeof target === "object", "extendObservable expects an object as first argument");
invariant(!(isObservableMap(target)), "extendObservable should not be used on maps, use map.merge instead");
invariant(arguments.length >= 2, getMessage("m014"));
invariant(typeof target === "object", getMessage("m015"));
invariant(!(isObservableMap(target)), getMessage("m016"));

properties.forEach(propSet => {
invariant(typeof propSet === "object", "all arguments of extendObservable should be objects");
invariant(!isObservable(propSet), "extending an object with another observable (object) is not supported. Please construct an explicit propertymap, using `toJS` if need. See issue #540");
invariant(typeof propSet === "object", getMessage("m017"));
invariant(!isObservable(propSet), getMessage("m018"));
});

const adm = asObservableObject(target);
Expand Down
3 changes: 2 additions & 1 deletion src/api/isobservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {isObservableObject, ObservableObjectAdministration} from "../types/obser
import {isAtom} from "../core/atom";
import {isComputedValue} from "../core/computedvalue";
import {isReaction} from "../core/reaction";
import {getMessage} from "../utils/messages";

/**
* Returns true if the provided value is reactive.
Expand All @@ -15,7 +16,7 @@ export function isObservable(value, property?: string): boolean {
return false;
if (property !== undefined) {
if (isObservableArray(value) || isObservableMap(value))
throw new Error("[mobx.isObservable] isObservable(object, propertyName) is not supported for arrays and maps. Use map.has or array.length instead.");
throw new Error(getMessage("m019"));
else if (isObservableObject(value)) {
const o = <ObservableObjectAdministration> (value as any).$mobx;
return o.values && !!o.values[property];
Expand Down
6 changes: 4 additions & 2 deletions src/api/observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {isObservable} from "./isobservable";
import {IObservableObject, asObservableObject} from "../types/observableobject";
import {extendObservable, extendShallowObservable} from "../api/extendobservable";
import {IObservableMapInitialValues, ObservableMap, IMap} from "../types/observablemap";
import {getMessage} from "../utils/messages";


const deepDecorator = createDecoratorForEnhancer(deepEnhancer);
const shallowDecorator = createDecoratorForEnhancer(shallowEnhancer);
Expand All @@ -23,8 +25,8 @@ function createObservable(v: any = undefined) {
if (typeof arguments[1] === "string")
return deepDecorator.apply(null, arguments);

invariant(arguments.length <= 1, "observable expects zero or one arguments");
invariant(!isModifierDescriptor(v), "modifiers can only be used for individual object properties");
invariant(arguments.length <= 1, getMessage("m021"));
invariant(!isModifierDescriptor(v), getMessage("m020"));

// it is an observable already, done
if (isObservable(v))
Expand Down
4 changes: 3 additions & 1 deletion src/api/observabledecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import {asObservableObject, defineObservableProperty, setPropertyValue} from "..
import {invariant, assertPropertyConfigurable} from "../utils/utils";
import {createClassPropertyDecorator} from "../utils/decorators";
import {IEnhancer} from "../types/modifiers";
import {getMessage} from "../utils/messages";


export function createDecoratorForEnhancer(enhancer: IEnhancer<any>) {
invariant(!!enhancer, ":(");
return createClassPropertyDecorator(
(target, name, baseValue, _, baseDescriptor) => {
assertPropertyConfigurable(target, name);
invariant(!baseDescriptor || !baseDescriptor.get, "@observable can not be used on getters, use @computed instead");
invariant(!baseDescriptor || !baseDescriptor.get, getMessage("m022"));

// might happen lazily (on first read), so temporarily allow state changes..
const prevA = allowStateChangesStart(true);
Expand Down
4 changes: 3 additions & 1 deletion src/api/transaction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {deprecated} from "../utils/utils";
import {executeAction} from "../core/action";
import {getMessage} from "../utils/messages";


/**
* @deprecated
Expand All @@ -12,7 +14,7 @@ import {executeAction} from "../core/action";
* @returns any value that was returned by the 'action' parameter.
*/
export function transaction<T>(action: () => T, thisArg = undefined): T {
deprecated("Using `transaction` is deprecated, use `runInAction` or `(@)action` instead.");
deprecated(getMessage("m023"));
return runInTransaction.apply(undefined, arguments);
}

Expand Down
5 changes: 3 additions & 2 deletions src/api/whyrun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {isComputedValue} from "../core/computedvalue";
import {isReaction} from "../core/reaction";
import {getAtom} from "../types/type-utils";
import {fail, deprecated} from "../utils/utils";
import {getMessage} from "../utils/messages";

function log(msg: string): string {
console.log(msg);
Expand All @@ -14,7 +15,7 @@ export function whyRun(thing?: any, prop?: string) {
case 0:
thing = globalState.trackingDerivation;
if (!thing)
return log("whyRun() can only be used if a derivation is active, or by passing an computed value / reaction explicitly. If you invoked whyRun from inside a computation; the computation is currently suspended but re-evaluating because somebody requested its value.");
return log(getMessage("m024"));
break;
case 2:
thing = getAtom(thing, prop);
Expand All @@ -25,5 +26,5 @@ export function whyRun(thing?: any, prop?: string) {
return log(thing.whyRun());
else if (isReaction(thing))
return log(thing.whyRun());
return fail("whyRun can only be used on reactions and computed values");
return fail(getMessage("m025"));
}
8 changes: 5 additions & 3 deletions src/core/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {startBatch, endBatch} from "../core/observable";
import {isSpyEnabled, spyReportStart, spyReportEnd} from "../core/spy";
import {isComputedValue} from "../core/computedvalue";
import {globalState} from "../core/globalstate";
import {getMessage} from "../utils/messages";


export function createAction(actionName: string, fn: Function): Function {
invariant(typeof fn === "function", "`action` can only be invoked on functions");
invariant(typeof fn === "function", getMessage("m026"));
invariant(typeof actionName === "string" && actionName.length > 0, `actions should have valid names, got: '${actionName}'`);
const res = function () {
return executeAction(actionName, fn, this, arguments);
Expand Down Expand Up @@ -36,7 +38,7 @@ interface IActionRunInfo {

function startAction(actionName: string, fn: Function, scope: any, args?: IArguments): IActionRunInfo {
// actions should not be called from computeds. check only works if the computed is actively observed, but that is fine enough as heuristic
invariant(!isComputedValue(globalState.trackingDerivation), "Computed values or transformers should not invoke actions or trigger other side effects");
invariant(!isComputedValue(globalState.trackingDerivation), getMessage("m027"));

const notifySpy = isSpyEnabled() && !!actionName;
let startTime: number = 0;
Expand Down Expand Up @@ -74,7 +76,7 @@ function endAction(runInfo: IActionRunInfo) {
}

export function useStrict(strict: boolean): any {
invariant(globalState.trackingDerivation === null, "It is not allowed to set `useStrict` when a derivation is running");
invariant(globalState.trackingDerivation === null, getMessage("m028"));
globalState.strictMode = strict;
globalState.allowStateChanges = !strict;
}
Expand Down
18 changes: 6 additions & 12 deletions src/core/computedvalue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {createInstanceofPredicate, getNextId, valueDidChange, invariant, Lambda,
import {isSpyEnabled, spyReport} from "../core/spy";
import {autorun} from "../api/autorun";
import {IValueDidChange} from "../types/observablevalue";
import {getMessage} from "../utils/messages";


export interface IComputedValue<T> {
get(): T;
Expand Down Expand Up @@ -71,7 +73,7 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
}

onBecomeUnobserved() {
invariant(this.dependenciesState !== IDerivationState.NOT_TRACKING, "INTERNAL ERROR only onBecomeUnobserved shouldn't be called twice in a row");
invariant(this.dependenciesState !== IDerivationState.NOT_TRACKING, getMessage("m029"));
clearObserving(this);
this.value = undefined;
}
Expand Down Expand Up @@ -195,20 +197,12 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
WhyRun? computation '${this.name}':
* Running because: ${isTracking ? "[active] the value of this computation is needed by a reaction" : this.isComputing ? "[get] The value of this computed was requested outside a reaction" : "[idle] not running at the moment"}
` +
(this.dependenciesState === IDerivationState.NOT_TRACKING
?
` * This computation is suspended (not in use by any reaction) and won't run automatically.
Didn't expect this computation to be suspended at this point?
1. Make sure this computation is used by a reaction (reaction, autorun, observer).
2. Check whether you are using this computation synchronously (in the same stack as they reaction that needs it).
`
:
(this.dependenciesState === IDerivationState.NOT_TRACKING ? getMessage("m032") :
` * This computation will re-run if any of the following observables changes:
${joinStrings(observing)}
${(this.isComputing && isTracking) ? " (... or any observable accessed during the remainder of the current run)" : ""}
Missing items in this list?
1. Check whether all used values are properly marked as observable (use isObservable to verify)
2. Make sure you didn't dereference values too early. MobX observes props, not primitives. E.g: use 'person.name' instead of 'name' in your computation.
${getMessage("m038")}

* If the outcome of this computation changes, the following observers will be re-run:
${joinStrings(observers)}
`
Expand Down
6 changes: 4 additions & 2 deletions src/core/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {IObservable, IDepTreeNode, addObserver, removeObserver} from "./observab
import {globalState} from "./globalstate";
import {invariant} from "../utils/utils";
import {isComputedValue} from "./computedvalue";
import {getMessage} from "../utils/messages";


export enum IDerivationState {
// before being run or (outside batch and not being observed)
Expand Down Expand Up @@ -103,8 +105,8 @@ export function isComputingDerivation() {
export function checkIfStateModificationsAreAllowed() {
if (!globalState.allowStateChanges) {
invariant(false, globalState.strictMode
? "It is not allowed to create or change state outside an `action` when MobX is in strict mode. Wrap the current method in `action` if this state change is intended"
: "It is not allowed to change the state when a computed value or transformer is being evaluated. Use 'autorun' to create reactive functions with side-effects."
? getMessage("m030")
:getMessage("m031")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space after :

);
}
}
Expand Down
Loading