Skip to content

Commit

Permalink
Introduced enforceActions: "strict" mode, fixes #1473
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Apr 16, 2018
1 parent b9ab050 commit d17e73c
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 16 deletions.
2 changes: 1 addition & 1 deletion flow-typed/mobx.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
export type IObservableMapInitialValues<K, V> = IMapEntries<K, V> | KeyValueMap<V> | IMap<K, V>

export interface IMobxConfigurationOptions {
enforceActions?: boolean,
enforceActions?: boolean | "strict",
computedRequiresReaction?: boolean,
isolateGlobalState?: boolean,
disableErrorBoundaries?: boolean,
Expand Down
36 changes: 23 additions & 13 deletions src/api/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,44 @@ import { reserveArrayBuffer } from "../types/observablearray"
import { setReactionScheduler } from "../core/reaction"

export function configure(options: {
enforceActions?: boolean
enforceActions?: boolean | "strict"
computedRequiresReaction?: boolean
isolateGlobalState?: boolean
disableErrorBoundaries?: boolean
arrayBuffer?: number
reactionScheduler?: (f: () => void) => void
}): void {
if (options.enforceActions !== undefined) {
globalState.enforceActions = !!options.enforceActions
globalState.allowStateChanges = !options.enforceActions
const {
enforceActions,
computedRequiresReaction,
disableErrorBoundaries,
arrayBuffer,
reactionScheduler
} = options
if (enforceActions !== undefined) {
if (typeof enforceActions !== "boolean" && enforceActions !== "strict")
return fail(`Invalid configuration for 'enforceActions': ${enforceActions}`)
globalState.enforceActions = enforceActions
globalState.allowStateChanges =
enforceActions === true || enforceActions === "strict" ? false : true
}
if (options.computedRequiresReaction !== undefined) {
globalState.computedRequiresReaction = !!options.computedRequiresReaction
if (computedRequiresReaction !== undefined) {
globalState.computedRequiresReaction = !!computedRequiresReaction
}
if (options.isolateGlobalState === true) {
isolateGlobalState()
}
if (options.disableErrorBoundaries !== undefined) {
if (options.disableErrorBoundaries === true)
if (disableErrorBoundaries !== undefined) {
if (disableErrorBoundaries === true)
console.warn(
"WARNING: Debug feature only. MobX will NOT recover from errors if this is on."
)
globalState.disableErrorBoundaries = !!options.disableErrorBoundaries
globalState.disableErrorBoundaries = !!disableErrorBoundaries
}
if (typeof options.arrayBuffer === "number") {
reserveArrayBuffer(options.arrayBuffer)
if (typeof arrayBuffer === "number") {
reserveArrayBuffer(arrayBuffer)
}
if (options.reactionScheduler) {
setReactionScheduler(options.reactionScheduler)
if (reactionScheduler) {
setReactionScheduler(reactionScheduler)
}
}
2 changes: 1 addition & 1 deletion src/core/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export function checkIfStateModificationsAreAllowed(atom: IAtom) {
`Computed values are not allowed to cause side effects by changing observables that are already being observed. Tried to modify: ${atom.name}`
)
// Should not be possible to change observed state outside strict mode, except during initialization, see #563
if (!globalState.allowStateChanges && hasObservers)
if (!globalState.allowStateChanges && (hasObservers || globalState.enforceActions === "strict"))
fail(
process.env.NODE_ENV !== "production" &&
(globalState.enforceActions
Expand Down
2 changes: 1 addition & 1 deletion src/core/globalstate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class MobXGlobals {
/**
* If strict mode is enabled, state changes are by default not allowed
*/
enforceActions = false
enforceActions: boolean | "strict" = false

/**
* Spy callbacks
Expand Down
24 changes: 24 additions & 0 deletions test/base/strict-mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@ test("strict mode checks", function() {
d()
})

test("enforceActions 'strict' does not allow changing unobserved observables", () => {
try {
mobx.configure({ enforceActions: "strict" })
const x = mobx.observable({
a: 1,
b: 2
})
const d = mobx.autorun(() => {
x.a
})

expect(() => {
x.a = 2
}).toThrow(/Since strict-mode is enabled/)
expect(() => {
x.b = 2
}).toThrow(/Since strict-mode is enabled/)

d()
} finally {
mobx.configure({ enforceActions: false })
}
})

test("warn on unsafe reads", function() {
try {
mobx.configure({ computedRequiresReaction: true })
Expand Down

1 comment on commit d17e73c

@Bnaya
Copy link
Member

@Bnaya Bnaya commented on d17e73c May 2, 2018

Choose a reason for hiding this comment

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

mobx.configure({ enforceActions: "strict" }) fail setting initial value of @observable class members

Please sign in to comment.