From d5d91956d11657969286f570422f56809f6ed859 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Thu, 20 Sep 2018 18:48:46 +0200 Subject: [PATCH 01/22] Switched to stage 2 decorator implementation --- test/.babelrc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/.babelrc b/test/.babelrc index 6c10c5cfa..6c1d565b9 100644 --- a/test/.babelrc +++ b/test/.babelrc @@ -1,7 +1,7 @@ { "presets": ["@babel/preset-env"], "plugins": [ - ["@babel/plugin-proposal-decorators", { "legacy": true}], - ["@babel/plugin-proposal-class-properties", { "loose": true}] + ["@babel/plugin-proposal-decorators", { "legacy": false, "decoratorsBeforeExport": true }], + ["@babel/plugin-proposal-class-properties", { "loose": false }] ] -} \ No newline at end of file +} From 3d3ee187660979c5315b1fec45f18c04c3c5cc25 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 15:08:11 +0200 Subject: [PATCH 02/22] First implementation of stage 2 decorators --- src/api/action.ts | 10 +++++-- src/api/actiondecorator.ts | 50 +++++++++++++++++++++++++++++++- src/api/computed.ts | 5 ++-- src/api/observable.ts | 5 ++-- src/api/observabledecorator.ts | 5 ++-- src/utils/decorators.ts | 53 +++++++++++++++++++++++++++++++++- test/base/babel-tests.js | 16 ++++------ 7 files changed, 123 insertions(+), 21 deletions(-) diff --git a/src/api/action.ts b/src/api/action.ts index 9e28fa058..34291be5e 100644 --- a/src/api/action.ts +++ b/src/api/action.ts @@ -40,7 +40,11 @@ export interface IActionFactory { (name: string, fn: T): T & IAction // named decorator - (customName: string): (target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor) => void + (customName: string): ( + target: Object, + key: string | symbol, + baseDescriptor?: PropertyDescriptor + ) => void // unnamed decorator (target: Object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void @@ -64,7 +68,9 @@ export var action: IActionFactory = function action(arg1, arg2?, arg3?, arg4?): // apply to instance immediately addHiddenProp(arg1, arg2, createAction(arg1.name || arg2, arg3.value)) } else { - return namedActionDecorator(arg2).apply(null, arguments) + // arg2: legacy decorators + // arg1.key: stage2 decorators + return namedActionDecorator(arg2 || arg1.key).apply(null, arguments) } } as any diff --git a/src/api/actiondecorator.ts b/src/api/actiondecorator.ts index d7086e561..de1b61f6b 100644 --- a/src/api/actiondecorator.ts +++ b/src/api/actiondecorator.ts @@ -4,7 +4,9 @@ import { addHiddenProp, createAction, defineBoundAction, - fail + fail, + quacksLikeAStage2Decorator, + Stage2Decorator } from "../internal" function dontReassignFields() { @@ -13,6 +15,32 @@ function dontReassignFields() { export function namedActionDecorator(name: string) { return function(target, prop, descriptor: BabelDescriptor) { + if (quacksLikeAStage2Decorator(arguments)) { + const decorator = target as Stage2Decorator + // @action.bound method() {} + if (decorator.kind === "method") { + const { descriptor } = decorator + if (process.env.NODE_ENV !== "production" && descriptor.get !== undefined) { + return fail("@action cannot be used with getters") + } + return { + ...decorator, + descriptor: { + ...descriptor, + value: createAction(name, descriptor.value) + } + } + } else { + // @action.bound method = () => {} + // kind = field + return { + ...decorator, + initializer() { + return createAction(name, decorator.initializer.call(this)) + } + } + } + } if (descriptor) { if (process.env.NODE_ENV !== "production" && descriptor.get !== undefined) { return fail("@action cannot be used with getters") @@ -66,6 +94,26 @@ export function boundActionDecorator(target, propertyName, descriptor, applyToIn defineBoundAction(target, propertyName, descriptor.value) return null } + if (quacksLikeAStage2Decorator(arguments)) { + // @action.bound method() and // @action.bound method = () => {} + const decorator = target as Stage2Decorator + return { + kind: "field", + placement: "own", + key: decorator.key, + descriptor: { + configurable: true, + enumerable: false, + writable: true + }, + initializer() { + const fn = decorator.initializer + ? decorator.initializer.call(this) + : decorator.descriptor.value + return createAction(decorator.key, fn.bind(this)) + } + } + } if (descriptor) { // if (descriptor.value) // Typescript / Babel: @action.bound method() { } diff --git a/src/api/computed.ts b/src/api/computed.ts index 274858a79..009a6c52f 100644 --- a/src/api/computed.ts +++ b/src/api/computed.ts @@ -5,7 +5,8 @@ import { asObservableObject, comparer, createPropDecorator, - invariant + invariant, + quacksLikeAStage2Decorator } from "../internal" export interface IComputed { @@ -45,7 +46,7 @@ const computedStructDecorator = computedDecorator({ equals: comparer.structural * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`; */ export var computed: IComputed = function computed(arg1, arg2, arg3) { - if (typeof arg2 === "string") { + if (typeof arg2 === "string" || quacksLikeAStage2Decorator(arguments)) { // @computed return computedDecorator.apply(null, arguments) } diff --git a/src/api/observable.ts b/src/api/observable.ts index 75c15696c..ad4b8d264 100644 --- a/src/api/observable.ts +++ b/src/api/observable.ts @@ -20,7 +20,8 @@ import { referenceEnhancer, shallowEnhancer, getDefaultDecoratorFromObjectOptions, - extendObservableObjectWithProperties + extendObservableObjectWithProperties, + quacksLikeAStage2Decorator } from "../internal" export type CreateObservableOptions = { @@ -74,7 +75,7 @@ function getEnhancerFromOptions(options: CreateObservableOptions): IEnhancer): IObservabl ? function observableDecorator() { // This wrapper function is just to detect illegal decorator invocations, deprecate in a next version // and simply return the created prop decorator - if (arguments.length < 2) + if (arguments.length < 2 && !quacksLikeAStage2Decorator(arguments)) return fail( "Incorrect decorator invocation. @observable decorator doesn't expect any arguments" ) diff --git a/src/utils/decorators.ts b/src/utils/decorators.ts index ab6232762..824d82c18 100644 --- a/src/utils/decorators.ts +++ b/src/utils/decorators.ts @@ -26,6 +26,15 @@ type DecoratorInvocationDescription = { decoratorArguments: any[] } +export type Stage2Decorator = { + kind: "field" | "method" | "class" + key: string + placement: "static" | "prototype" | "own" + descriptor: PropertyDescriptor + initializer?: () => any + finisher?: (klass) => void +} + const enumerableDescriptorCache: { [prop: string]: PropertyDescriptor } = {} const nonEnumerableDescriptorCache: { [prop: string]: PropertyDescriptor } = {} @@ -79,6 +88,44 @@ export function createPropDecorator( // This is a special parameter to signal the direct application of a decorator, allow extendObservable to skip the entire type decoration part, // as the instance to apply the decorator to equals the target ) { + if (quacksLikeAStage2Decorator(arguments)) { + const stage2decorator = target as Stage2Decorator + const key = stage2decorator.key + return { + kind: "method", + placement: "own", + key, + descriptor: { + enumerable: propertyInitiallyEnumerable, + configurable: true, + get() { + // TODO: initializeInstance(this) + propertyCreator( + this, + key, + stage2decorator.descriptor, + this, + decoratorArguments + ) + if (stage2decorator.initializer) + this[key] = stage2decorator.initializer.call(this) + return this[key] + }, + set(v) { + // TODO: initializeInstance(this) + propertyCreator( + this, + key, + stage2decorator.descriptor, + this, + decoratorArguments + ) + this[key] = v + } + } + } + } + if (applyImmediately === true) { propertyCreator(target, prop, descriptor, target, decoratorArguments) return null @@ -99,7 +146,7 @@ export function createPropDecorator( return createPropertyInitializerDescriptor(prop, propertyInitiallyEnumerable) } - if (quacksLikeADecorator(arguments)) { + if (quacksLikeADecorator(arguments) || quacksLikeAStage2Decorator(arguments)) { // @decorator decoratorArguments = EMPTY_ARRAY return decorator.apply(null, arguments) @@ -117,3 +164,7 @@ export function quacksLikeADecorator(args: IArguments): boolean { (args.length === 4 && args[3] === true) ) } + +export function quacksLikeAStage2Decorator(args: IArguments): boolean { + return args.length === 1 && args[0] && (args[0].kind === "field" || args[0].kind === "method") +} diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 540739d19..bb81f5bf3 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -587,11 +587,7 @@ test("enumerability", () => { let props = [] for (var key in a) props.push(key) - expect(ownProps).toEqual( - [ - // should have a, not supported yet in babel... - ] - ) + expect(ownProps).toEqual(["a", "a2"]) expect(props).toEqual(["a", "a2"]) @@ -701,11 +697,9 @@ test("verify object assign (babel)", () => { } const todo = new Todo() - expect(Object.assign({}, todo)).toEqual( - { - // Should be: title: "test"! - } - ) + expect(Object.assign({}, todo)).toEqual({ + title: "test" + }) todo.title // lazy initialization :'( @@ -799,7 +793,7 @@ test("505, don't throw when accessing subclass fields in super constructor (babe } new B() - expect(values).toEqual({ a: 1, b: 2 }) // In the TS test b is undefined, which is actually the expected behavior? + expect(values).toEqual({ a: 1, b: undefined }) }) test("computed setter should succeed (babel)", function() { From bc572f09c21b929925086f6fb0d49f26c99e6500 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 15:47:11 +0200 Subject: [PATCH 03/22] Fixed unchecked exception in reaction test suite --- test/base/reaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/base/reaction.js b/test/base/reaction.js index b6a6c43c7..438ed6589 100644 --- a/test/base/reaction.js +++ b/test/base/reaction.js @@ -427,7 +427,7 @@ test("issue #1148", () => { const a = mobx.observable.box(1) let called = 0 const dispose = reaction( - () => this.a, + () => a.get(), () => { called++ }, From f9b7f0d868bb684c92dabc11feb8e72e4ba20013 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 15:53:35 +0200 Subject: [PATCH 04/22] Keep class properties `loose` to support `decorate` --- test/.babelrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/.babelrc b/test/.babelrc index 6c1d565b9..d792fe8db 100644 --- a/test/.babelrc +++ b/test/.babelrc @@ -2,6 +2,6 @@ "presets": ["@babel/preset-env"], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": false, "decoratorsBeforeExport": true }], - ["@babel/plugin-proposal-class-properties", { "loose": false }] + ["@babel/plugin-proposal-class-properties", { "loose": true }] ] } From c7990cfd259e3f1bfcc05a7fd127d99a492d2544 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 19:58:19 +0200 Subject: [PATCH 05/22] Minor fixes, skipped some tests --- src/api/actiondecorator.ts | 1 + test/base/babel-tests.js | 215 +++++++++++++++++++++++++------------ 2 files changed, 150 insertions(+), 66 deletions(-) diff --git a/src/api/actiondecorator.ts b/src/api/actiondecorator.ts index de1b61f6b..1892b8fe3 100644 --- a/src/api/actiondecorator.ts +++ b/src/api/actiondecorator.ts @@ -25,6 +25,7 @@ export function namedActionDecorator(name: string) { } return { ...decorator, + placement: "prototype", descriptor: { ...descriptor, value: createAction(name, descriptor.value) diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index bb81f5bf3..79979d372 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -18,9 +18,12 @@ import * as mobx from "../../src/mobx.ts" test("babel", function() { class Box { - @observable uninitialized - @observable height = 20 - @observable sizes = [2] + @observable + uninitialized + @observable + height = 20 + @observable + sizes = [2] @observable someFunc = function() { return 2 @@ -74,8 +77,10 @@ test("should not be possible to use @action with getters", () => { test("babel: parameterized computed decorator", () => { class TestClass { - @observable x = 3 - @observable y = 3 + @observable + x = 3 + @observable + y = 3 @computed.struct get boxedSum() { return { sum: Math.round(this.x) + Math.round(this.y) } @@ -104,7 +109,8 @@ test("babel: parameterized computed decorator", () => { test("computed value should be the same around changing which was considered equivalent", () => { class TestClass { - @observable c = null + @observable + c = null defaultCollection = [] @computed.struct get collection() { @@ -126,10 +132,14 @@ test("computed value should be the same around changing which was considered equ }) class Order { - @observable price = 3 - @observable amount = 2 - @observable orders = [] - @observable aFunction = function(a) {} + @observable + price = 3 + @observable + amount = 2 + @observable + orders = [] + @observable + aFunction = function(a) {} @computed get total() { @@ -139,8 +149,9 @@ class Order { test("decorators", function() { var o = new Order() - expect(isObservableObject(o)).toBe(true) - expect(isObservableProp(o, "amount")).toBe(true) + // Broken, see: https://github.com/tc39/proposal-decorators/issues/153 + // expect(isObservableObject(o)).toBe(true) + // expect(isObservableProp(o, "amount")).toBe(true) expect(o.total).toBe(6) // .... this is required to initialize the props which are made reactive lazily... expect(isObservableProp(o, "total")).toBe(true) @@ -157,6 +168,9 @@ test("decorators", function() { o.price = 5 + expect(isObservableObject(o)).toBe(true) + expect(isObservableProp(o, "amount")).toBe(true) + expect(events).toEqual([ 8, // new total 6, // old total @@ -169,8 +183,10 @@ test("decorators", function() { test("issue 191 - shared initializers (babel)", function() { class Test { - @observable obj = { a: 1 } - @observable array = [2] + @observable + obj = { a: 1 } + @observable + array = [2] } var t1 = new Test() @@ -195,8 +211,10 @@ test("705 - setter undoing caching (babel)", () => { let autoruns = 0 class Person { - @observable name - @observable title + @observable + name + @observable + title set fullName(val) { // Noop } @@ -413,7 +431,8 @@ test("267 (babel) should be possible to declare properties observable outside st configure({ enforceActions: true }) class Store { - @observable timer + @observable + timer } configure({ enforceActions: false }) @@ -421,7 +440,8 @@ test("267 (babel) should be possible to declare properties observable outside st test("288 atom not detected for object property", () => { class Store { - @mobx.observable foo = "" + @mobx.observable + foo = "" } const store = new Store() @@ -442,9 +462,12 @@ test.skip("observable performance", () => { const AMOUNT = 100000 class A { - @observable a = 1 - @observable b = 2 - @observable c = 3 + @observable + a = 1 + @observable + b = 2 + @observable + c = 3 @computed get d() { return this.a + this.b + this.c @@ -478,7 +501,8 @@ test("unbound methods", () => { m1() {} // per instance - @action m2 = () => {} + @action + m2 = () => {} } const a1 = new A() @@ -494,11 +518,13 @@ test("unbound methods", () => { test("inheritance", () => { class A { - @observable a = 2 + @observable + a = 2 } class B extends A { - @observable b = 3 + @observable + b = 3 @computed get c() { return this.a + this.b @@ -520,12 +546,15 @@ test("inheritance", () => { test("inheritance overrides observable", () => { class A { - @observable a = 2 + @observable + a = 2 } class B { - @observable a = 5 - @observable b = 3 + @observable + a = 5 + @observable + b = 3 @computed get c() { return this.a + this.b @@ -547,8 +576,10 @@ test("inheritance overrides observable", () => { test("reusing initializers", () => { class A { - @observable a = 3 - @observable b = this.a + 2 + @observable + a = 3 + @observable + b = this.a + 2 @computed get c() { return this.a + this.b @@ -567,17 +598,20 @@ test("reusing initializers", () => { expect(values).toEqual([9, 10]) }) -test("enumerability", () => { +test.skip("enumerability", () => { class A { - @observable a = 1 // enumerable, on proto - @observable a2 = 2 + @observable + a = 1 // enumerable, on proto + @observable + a2 = 2 @computed get b() { return this.a } // non-enumerable, on proto @action m() {} // non-enumerable, on proto - @action m2 = () => {} // non-enumerable, on self + @action + m2 = () => {} // non-enumerable, on self } const a = new A() @@ -592,8 +626,8 @@ test("enumerability", () => { expect(props).toEqual(["a", "a2"]) expect("a" in a).toBe(true) - expect(a.hasOwnProperty("a")).toBe(false) // true would better.. - expect(a.hasOwnProperty("b")).toBe(false) + expect(a.hasOwnProperty("a")).toBe(true) + expect(a.hasOwnProperty("b")).toBe(true) // ideally false expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) @@ -611,31 +645,34 @@ test("enumerability", () => { for (var key in a) props.push(key) expect(ownProps).toEqual([ - "a", - "a2" // a2 is now initialized as well, altough never accessed! + "a" + // "a2" ideally should include a2 as well ]) expect(props).toEqual(["a", "a2"]) expect("a" in a).toBe(true) expect(a.hasOwnProperty("a")).toBe(true) - expect(a.hasOwnProperty("a2")).toBe(true) - expect(a.hasOwnProperty("b")).toBe(false) // true would also be ok-ish. see: #1398 + expect(a.hasOwnProperty("a2")).toBe(false) // ideally, true, but never accessed... + expect(a.hasOwnProperty("b")).toBe(true) // ideally, false. see: #1398 expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) }) -test("enumerability - workaround", () => { +test.skip("enumerability - workaround", () => { class A { - @observable a = 1 // enumerable, on proto - @observable a2 = 2 + @observable + a = 1 // enumerable, on proto + @observable + a2 = 2 @computed get b() { return this.a } // non-enumerable, on proto @action m() {} // non-enumerable, on proto - @action m2 = () => {} // non-enumerable, on self + @action + m2 = () => {} // non-enumerable, on self constructor() { this.a = 1 @@ -664,23 +701,51 @@ test("enumerability - workaround", () => { expect(a.hasOwnProperty("m2")).toBe(true) }) +test.skip("Babel bug", () => { + // See: https://github.com/babel/babel/issues/8760 + class Todo1 { + id = 1 + } + + function dec(el) { + return el + } + class Todo2 { + id = 1 + @dec + x + } + + const t1 = new Todo1() + expect(Object.getOwnPropertyDescriptor(t1, "id").enumerable).toBe(true) + + const t2 = new Todo2() + expect(Object.getOwnPropertyDescriptor(t2, "id").enumerable).toBe(true) // fails +}) + test("issue 285 (babel)", () => { const { observable, toJS } = mobx class Todo { id = 1 - @observable title - @observable finished = false - @observable childThings = [1, 2, 3] + @observable + title + @observable + finished = false + @observable + childThings = [1, 2, 3] constructor(title) { this.title = title } } var todo = new Todo("Something to do") + expect(todo.id).toBe(1) - expect(toJS(todo)).toEqual({ - id: 1, + const res = toJS(todo) + + expect(res).toEqual({ + // TODO: should inclue id: 1 // Babel 7 bug, see https://github.com/babel/babel/issues/8760 title: "Something to do", finished: false, childThings: [1, 2, 3] @@ -689,7 +754,8 @@ test("issue 285 (babel)", () => { test("verify object assign (babel)", () => { class Todo { - @observable title = "test" + @observable + title = "test" @computed get upperCase() { return this.title.toUpperCase() @@ -781,7 +847,8 @@ test("379, inheritable actions - 2 (babel)", () => { test("505, don't throw when accessing subclass fields in super constructor (babel)", () => { const values = {} class A { - @observable a = 1 + @observable + a = 1 constructor() { values.b = this.b values.a = this.a @@ -789,7 +856,8 @@ test("505, don't throw when accessing subclass fields in super constructor (babe } class B extends A { - @observable b = 2 + @observable + b = 2 } new B() @@ -798,7 +866,8 @@ test("505, don't throw when accessing subclass fields in super constructor (babe test("computed setter should succeed (babel)", function() { class Bla { - @observable a = 3 + @observable + a = 3 @computed get propX() { return this.a * 2 @@ -836,7 +905,8 @@ test("computed getter / setter for plan objects should succeed (babel)", functio test("issue #701", () => { class Model { - @observable a = 5 + @observable + a = 5 } const model = new Model() @@ -848,7 +918,8 @@ test("issue #701", () => { test("@observable.ref (Babel)", () => { class A { - @observable.ref ref = { a: 3 } + @observable.ref + ref = { a: 3 } } const a = new A() @@ -859,7 +930,8 @@ test("@observable.ref (Babel)", () => { test("@observable.shallow (Babel)", () => { class A { - @observable.shallow arr = [{ todo: 1 }] + @observable.shallow + arr = [{ todo: 1 }] } const a = new A() @@ -874,7 +946,8 @@ test("@observable.shallow (Babel)", () => { test("@observable.deep (Babel)", () => { class A { - @observable.deep arr = [{ todo: 1 }] + @observable.deep + arr = [{ todo: 1 }] } const a = new A() @@ -891,7 +964,8 @@ test("@observable.deep (Babel)", () => { test("action.bound binds (Babel)", () => { class A { - @observable x = 0 + @observable + x = 0 @action.bound inc(value) { this.x += value @@ -913,8 +987,10 @@ test("@computed.equals (Babel)", () => { this.minute = minute } - @observable hour - @observable minute + @observable + hour + @observable + minute @computed({ equals: sameTime }) get time() { @@ -1063,10 +1139,12 @@ test("actions are reassignable", () => { class A { @action m1() {} - @action m2 = () => {} + @action + m2 = () => {} @action.bound m3() {} - @action.bound m4 = () => {} + @action.bound + m4 = () => {} } const a = new A() @@ -1090,7 +1168,8 @@ test("it should support asyncAction (babel)", async () => { mobx.configure({ enforceActions: true }) class X { - @observable a = 1 + @observable + a = 1 f = mobx.flow(function* f(initial) { this.a = initial // this runs in action @@ -1121,8 +1200,10 @@ test("toJS bug #1413 (babel)", () => { test("computed setter problem", () => { class Contact { - @observable firstName = "" - @observable lastName = "" + @observable + firstName = "" + @observable + lastName = "" @computed({ set(value) { @@ -1158,8 +1239,10 @@ test("computed setter problem", () => { test("computed setter problem - 2", () => { class Contact { - @observable firstName = "" - @observable lastName = "" + @observable + firstName = "" + @observable + lastName = "" get fullName() { return `${this.firstName} ${this.lastName}` From ef0f674407f329a3ed6fa33550e4cab8722a67ef Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 20:31:34 +0200 Subject: [PATCH 06/22] Clean up action decorator --- src/api/actiondecorator.ts | 92 ++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/src/api/actiondecorator.ts b/src/api/actiondecorator.ts index 1892b8fe3..860916f49 100644 --- a/src/api/actiondecorator.ts +++ b/src/api/actiondecorator.ts @@ -16,31 +16,7 @@ function dontReassignFields() { export function namedActionDecorator(name: string) { return function(target, prop, descriptor: BabelDescriptor) { if (quacksLikeAStage2Decorator(arguments)) { - const decorator = target as Stage2Decorator - // @action.bound method() {} - if (decorator.kind === "method") { - const { descriptor } = decorator - if (process.env.NODE_ENV !== "production" && descriptor.get !== undefined) { - return fail("@action cannot be used with getters") - } - return { - ...decorator, - placement: "prototype", - descriptor: { - ...descriptor, - value: createAction(name, descriptor.value) - } - } - } else { - // @action.bound method = () => {} - // kind = field - return { - ...decorator, - initializer() { - return createAction(name, decorator.initializer.call(this)) - } - } - } + return stage2NamedActionDecorator(name, target) } if (descriptor) { if (process.env.NODE_ENV !== "production" && descriptor.get !== undefined) { @@ -74,6 +50,34 @@ export function namedActionDecorator(name: string) { } } +export function stage2NamedActionDecorator( + name: string, + elementDescriptor: Stage2Decorator +): Stage2Decorator { + const { kind, descriptor } = elementDescriptor + // @action method() {} + if (kind === "method") { + if (process.env.NODE_ENV !== "production" && descriptor.get !== undefined) { + return fail("@action cannot be used with getters") + } + return { + ...elementDescriptor, + descriptor: { + ...descriptor, + value: createAction(name, descriptor.value) + } + } + } else { + // @action.bound method = () => {} + return { + ...elementDescriptor, + initializer() { + return createAction(name, elementDescriptor.initializer!.call(this)) + } + } + } +} + export function actionFieldDecorator(name: string) { // Simple property that writes on first invocation to the current instance return function(target, prop, descriptor) { @@ -96,24 +100,7 @@ export function boundActionDecorator(target, propertyName, descriptor, applyToIn return null } if (quacksLikeAStage2Decorator(arguments)) { - // @action.bound method() and // @action.bound method = () => {} - const decorator = target as Stage2Decorator - return { - kind: "field", - placement: "own", - key: decorator.key, - descriptor: { - configurable: true, - enumerable: false, - writable: true - }, - initializer() { - const fn = decorator.initializer - ? decorator.initializer.call(this) - : decorator.descriptor.value - return createAction(decorator.key, fn.bind(this)) - } - } + return stage2BoundActionDecorator(target) } if (descriptor) { // if (descriptor.value) @@ -145,3 +132,22 @@ export function boundActionDecorator(target, propertyName, descriptor, applyToIn } } } + +function stage2BoundActionDecorator(elementDescriptor: Stage2Decorator): Stage2Decorator { + // @action.bound method() and // @action.bound method = () => {} + const { initializer, descriptor, key } = elementDescriptor + return { + key, + kind: "field", + placement: "own", + descriptor: { + configurable: true, + enumerable: false, + writable: true + }, + initializer() { + const fn = initializer ? initializer.call(this) : descriptor.value + return createAction(key, fn.bind(this)) + } + } +} From f44fc89cc4d331ca09e8a1d3e0c59840e90cb0c1 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 20:59:48 +0200 Subject: [PATCH 07/22] Restored tests --- test/base/babel-tests.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 79979d372..4f9b81ade 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -598,7 +598,7 @@ test("reusing initializers", () => { expect(values).toEqual([9, 10]) }) -test.skip("enumerability", () => { +test("enumerability", () => { class A { @observable a = 1 // enumerable, on proto @@ -644,22 +644,19 @@ test.skip("enumerability", () => { props = [] for (var key in a) props.push(key) - expect(ownProps).toEqual([ - "a" - // "a2" ideally should include a2 as well - ]) + expect(ownProps).toEqual(["a", "a2"]) expect(props).toEqual(["a", "a2"]) expect("a" in a).toBe(true) expect(a.hasOwnProperty("a")).toBe(true) - expect(a.hasOwnProperty("a2")).toBe(false) // ideally, true, but never accessed... + expect(a.hasOwnProperty("a2")).toBe(true) expect(a.hasOwnProperty("b")).toBe(true) // ideally, false. see: #1398 expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) }) -test.skip("enumerability - workaround", () => { +test("enumerability - workaround", () => { class A { @observable a = 1 // enumerable, on proto @@ -696,7 +693,7 @@ test.skip("enumerability - workaround", () => { expect("a" in a).toBe(true) expect(a.hasOwnProperty("a")).toBe(true) expect(a.hasOwnProperty("a2")).toBe(true) - expect(a.hasOwnProperty("b")).toBe(false) // true would also be ok-ish. see: #1398 + expect(a.hasOwnProperty("b")).toBe(true) // ideally false would also be ok-ish. see: #1398 expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) }) From 006c3120248c836abc607f9bdd1802272c96e9a0 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 21:10:16 +0200 Subject: [PATCH 08/22] Minor improvements --- src/utils/decorators.ts | 12 ++++-------- test/base/babel-tests.js | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/utils/decorators.ts b/src/utils/decorators.ts index 824d82c18..7ce8c88e5 100644 --- a/src/utils/decorators.ts +++ b/src/utils/decorators.ts @@ -90,33 +90,29 @@ export function createPropDecorator( ) { if (quacksLikeAStage2Decorator(arguments)) { const stage2decorator = target as Stage2Decorator - const key = stage2decorator.key + const { key, descriptor, initializer } = stage2decorator return { kind: "method", - placement: "own", + placement: propertyInitiallyEnumerable ? "own" : "prototype", // Ideally, we want to use prototype here, but that get's to hairy... key, descriptor: { enumerable: propertyInitiallyEnumerable, configurable: true, get() { - // TODO: initializeInstance(this) propertyCreator( this, key, - stage2decorator.descriptor, + { ...descriptor, initializer }, this, decoratorArguments ) - if (stage2decorator.initializer) - this[key] = stage2decorator.initializer.call(this) return this[key] }, set(v) { - // TODO: initializeInstance(this) propertyCreator( this, key, - stage2decorator.descriptor, + { ...descriptor, initializer }, this, decoratorArguments ) diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 4f9b81ade..c411aca7e 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -627,7 +627,7 @@ test("enumerability", () => { expect("a" in a).toBe(true) expect(a.hasOwnProperty("a")).toBe(true) - expect(a.hasOwnProperty("b")).toBe(true) // ideally false + expect(a.hasOwnProperty("b")).toBe(false) // ideally false expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) @@ -693,7 +693,7 @@ test("enumerability - workaround", () => { expect("a" in a).toBe(true) expect(a.hasOwnProperty("a")).toBe(true) expect(a.hasOwnProperty("a2")).toBe(true) - expect(a.hasOwnProperty("b")).toBe(true) // ideally false would also be ok-ish. see: #1398 + expect(a.hasOwnProperty("b")).toBe(false) // ideally false, true would also be ok-ish. see: #1398 expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) }) From 152805ea871909e6ba8a1705dfd5014f1bfc4945 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 21:14:46 +0200 Subject: [PATCH 09/22] Lowered prettier version to fix formatting --- package.json | 2 +- src/utils/decorators.ts | 2 +- test/base/babel-tests.js | 165 +++++++++++++-------------------------- yarn.lock | 6 +- 4 files changed, 60 insertions(+), 115 deletions(-) diff --git a/package.json b/package.json index 950ddb6f7..16faa5abc 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "lodash.intersection": "^3.2.0", "ncp": "^2.0.0", "nscript": "^0.1.10", - "prettier": "^1.4.4", + "prettier": "~1.13.0", "regenerator-runtime": "^0.11.1", "rollup": "^0.41.6", "rollup-plugin-filesize": "^1.3.2", diff --git a/src/utils/decorators.ts b/src/utils/decorators.ts index 7ce8c88e5..f8f38ad0b 100644 --- a/src/utils/decorators.ts +++ b/src/utils/decorators.ts @@ -93,7 +93,7 @@ export function createPropDecorator( const { key, descriptor, initializer } = stage2decorator return { kind: "method", - placement: propertyInitiallyEnumerable ? "own" : "prototype", // Ideally, we want to use prototype here, but that get's to hairy... + placement: propertyInitiallyEnumerable ? "own" : "prototype", key, descriptor: { enumerable: propertyInitiallyEnumerable, diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index c411aca7e..69c0f3285 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -18,12 +18,9 @@ import * as mobx from "../../src/mobx.ts" test("babel", function() { class Box { - @observable - uninitialized - @observable - height = 20 - @observable - sizes = [2] + @observable uninitialized + @observable height = 20 + @observable sizes = [2] @observable someFunc = function() { return 2 @@ -77,10 +74,8 @@ test("should not be possible to use @action with getters", () => { test("babel: parameterized computed decorator", () => { class TestClass { - @observable - x = 3 - @observable - y = 3 + @observable x = 3 + @observable y = 3 @computed.struct get boxedSum() { return { sum: Math.round(this.x) + Math.round(this.y) } @@ -109,8 +104,7 @@ test("babel: parameterized computed decorator", () => { test("computed value should be the same around changing which was considered equivalent", () => { class TestClass { - @observable - c = null + @observable c = null defaultCollection = [] @computed.struct get collection() { @@ -132,14 +126,10 @@ test("computed value should be the same around changing which was considered equ }) class Order { - @observable - price = 3 - @observable - amount = 2 - @observable - orders = [] - @observable - aFunction = function(a) {} + @observable price = 3 + @observable amount = 2 + @observable orders = [] + @observable aFunction = function(a) {} @computed get total() { @@ -183,10 +173,8 @@ test("decorators", function() { test("issue 191 - shared initializers (babel)", function() { class Test { - @observable - obj = { a: 1 } - @observable - array = [2] + @observable obj = { a: 1 } + @observable array = [2] } var t1 = new Test() @@ -211,10 +199,8 @@ test("705 - setter undoing caching (babel)", () => { let autoruns = 0 class Person { - @observable - name - @observable - title + @observable name + @observable title set fullName(val) { // Noop } @@ -431,8 +417,7 @@ test("267 (babel) should be possible to declare properties observable outside st configure({ enforceActions: true }) class Store { - @observable - timer + @observable timer } configure({ enforceActions: false }) @@ -440,8 +425,7 @@ test("267 (babel) should be possible to declare properties observable outside st test("288 atom not detected for object property", () => { class Store { - @mobx.observable - foo = "" + @mobx.observable foo = "" } const store = new Store() @@ -462,12 +446,9 @@ test.skip("observable performance", () => { const AMOUNT = 100000 class A { - @observable - a = 1 - @observable - b = 2 - @observable - c = 3 + @observable a = 1 + @observable b = 2 + @observable c = 3 @computed get d() { return this.a + this.b + this.c @@ -501,8 +482,7 @@ test("unbound methods", () => { m1() {} // per instance - @action - m2 = () => {} + @action m2 = () => {} } const a1 = new A() @@ -518,13 +498,11 @@ test("unbound methods", () => { test("inheritance", () => { class A { - @observable - a = 2 + @observable a = 2 } class B extends A { - @observable - b = 3 + @observable b = 3 @computed get c() { return this.a + this.b @@ -546,15 +524,12 @@ test("inheritance", () => { test("inheritance overrides observable", () => { class A { - @observable - a = 2 + @observable a = 2 } class B { - @observable - a = 5 - @observable - b = 3 + @observable a = 5 + @observable b = 3 @computed get c() { return this.a + this.b @@ -576,10 +551,8 @@ test("inheritance overrides observable", () => { test("reusing initializers", () => { class A { - @observable - a = 3 - @observable - b = this.a + 2 + @observable a = 3 + @observable b = this.a + 2 @computed get c() { return this.a + this.b @@ -600,18 +573,15 @@ test("reusing initializers", () => { test("enumerability", () => { class A { - @observable - a = 1 // enumerable, on proto - @observable - a2 = 2 + @observable a = 1 // enumerable, on proto + @observable a2 = 2 @computed get b() { return this.a } // non-enumerable, on proto @action m() {} // non-enumerable, on proto - @action - m2 = () => {} // non-enumerable, on self + @action m2 = () => {} // non-enumerable, on self } const a = new A() @@ -658,18 +628,15 @@ test("enumerability", () => { test("enumerability - workaround", () => { class A { - @observable - a = 1 // enumerable, on proto - @observable - a2 = 2 + @observable a = 1 // enumerable, on proto + @observable a2 = 2 @computed get b() { return this.a } // non-enumerable, on proto @action m() {} // non-enumerable, on proto - @action - m2 = () => {} // non-enumerable, on self + @action m2 = () => {} // non-enumerable, on self constructor() { this.a = 1 @@ -709,8 +676,7 @@ test.skip("Babel bug", () => { } class Todo2 { id = 1 - @dec - x + @dec x } const t1 = new Todo1() @@ -725,12 +691,9 @@ test("issue 285 (babel)", () => { class Todo { id = 1 - @observable - title - @observable - finished = false - @observable - childThings = [1, 2, 3] + @observable title + @observable finished = false + @observable childThings = [1, 2, 3] constructor(title) { this.title = title } @@ -751,8 +714,7 @@ test("issue 285 (babel)", () => { test("verify object assign (babel)", () => { class Todo { - @observable - title = "test" + @observable title = "test" @computed get upperCase() { return this.title.toUpperCase() @@ -844,8 +806,7 @@ test("379, inheritable actions - 2 (babel)", () => { test("505, don't throw when accessing subclass fields in super constructor (babel)", () => { const values = {} class A { - @observable - a = 1 + @observable a = 1 constructor() { values.b = this.b values.a = this.a @@ -853,8 +814,7 @@ test("505, don't throw when accessing subclass fields in super constructor (babe } class B extends A { - @observable - b = 2 + @observable b = 2 } new B() @@ -863,8 +823,7 @@ test("505, don't throw when accessing subclass fields in super constructor (babe test("computed setter should succeed (babel)", function() { class Bla { - @observable - a = 3 + @observable a = 3 @computed get propX() { return this.a * 2 @@ -902,8 +861,7 @@ test("computed getter / setter for plan objects should succeed (babel)", functio test("issue #701", () => { class Model { - @observable - a = 5 + @observable a = 5 } const model = new Model() @@ -915,8 +873,7 @@ test("issue #701", () => { test("@observable.ref (Babel)", () => { class A { - @observable.ref - ref = { a: 3 } + @observable.ref ref = { a: 3 } } const a = new A() @@ -927,8 +884,7 @@ test("@observable.ref (Babel)", () => { test("@observable.shallow (Babel)", () => { class A { - @observable.shallow - arr = [{ todo: 1 }] + @observable.shallow arr = [{ todo: 1 }] } const a = new A() @@ -943,8 +899,7 @@ test("@observable.shallow (Babel)", () => { test("@observable.deep (Babel)", () => { class A { - @observable.deep - arr = [{ todo: 1 }] + @observable.deep arr = [{ todo: 1 }] } const a = new A() @@ -961,8 +916,7 @@ test("@observable.deep (Babel)", () => { test("action.bound binds (Babel)", () => { class A { - @observable - x = 0 + @observable x = 0 @action.bound inc(value) { this.x += value @@ -984,10 +938,8 @@ test("@computed.equals (Babel)", () => { this.minute = minute } - @observable - hour - @observable - minute + @observable hour + @observable minute @computed({ equals: sameTime }) get time() { @@ -1136,12 +1088,10 @@ test("actions are reassignable", () => { class A { @action m1() {} - @action - m2 = () => {} + @action m2 = () => {} @action.bound m3() {} - @action.bound - m4 = () => {} + @action.bound m4 = () => {} } const a = new A() @@ -1165,8 +1115,7 @@ test("it should support asyncAction (babel)", async () => { mobx.configure({ enforceActions: true }) class X { - @observable - a = 1 + @observable a = 1 f = mobx.flow(function* f(initial) { this.a = initial // this runs in action @@ -1197,10 +1146,8 @@ test("toJS bug #1413 (babel)", () => { test("computed setter problem", () => { class Contact { - @observable - firstName = "" - @observable - lastName = "" + @observable firstName = "" + @observable lastName = "" @computed({ set(value) { @@ -1236,10 +1183,8 @@ test("computed setter problem", () => { test("computed setter problem - 2", () => { class Contact { - @observable - firstName = "" - @observable - lastName = "" + @observable firstName = "" + @observable lastName = "" get fullName() { return `${this.firstName} ${this.lastName}` diff --git a/yarn.lock b/yarn.lock index eaf5ccc5d..5d32daa6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4895,9 +4895,9 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -prettier@^1.4.4: - version "1.12.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" +prettier@~1.13.0: + version "1.13.7" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" pretty-format@^22.4.0, pretty-format@^22.4.3: version "22.4.3" From afdb00ff79b4be74126b88f6837f25b4aaff7b81 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 21:44:57 +0200 Subject: [PATCH 10/22] Cleaner code path separation for stage2 computed --- src/api/computed.ts | 61 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/src/api/computed.ts b/src/api/computed.ts index 009a6c52f..db55f68f4 100644 --- a/src/api/computed.ts +++ b/src/api/computed.ts @@ -8,6 +8,8 @@ import { invariant, quacksLikeAStage2Decorator } from "../internal" +import { Stage2Decorator } from "../utils/decorators" +import { EMPTY_OBJECT } from "../utils/utils" export interface IComputed { (options: IComputedValueOptions): any // decorator @@ -17,7 +19,7 @@ export interface IComputed { struct(target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor): void // decorator } -export const computedDecorator = createPropDecorator( +const classicComputedDecorator = createPropDecorator( false, ( instance: any, @@ -29,7 +31,7 @@ export const computedDecorator = createPropDecorator( const { get, set } = descriptor // initialValue is the descriptor for get / set props // Optimization: faster on decorator target or instance? Assuming target // Optimization: find out if declaring on instance isn't just faster. (also makes the property descriptor simpler). But, more memory usage.. - const options = decoratorArgs[0] || {} + const options = decoratorArgs[0] || EMPTY_OBJECT asObservableObject(instance).addComputedProp(decoratorTarget, propertyName, { get, set, @@ -39,6 +41,18 @@ export const computedDecorator = createPropDecorator( } ) +export const computedDecorator = function computedDecorator(arg1) { + if (arguments.length > 1) return classicComputedDecorator.apply(null, arguments) + if (quacksLikeAStage2Decorator(arguments)) { + return stage2ComputedDecorator(EMPTY_OBJECT, arg1) + } + return function() { + if (quacksLikeAStage2Decorator(arguments)) + return stage2ComputedDecorator(arg1, arguments[0]) + else return classicComputedDecorator(arg1).apply(null, arguments) + } +} + const computedStructDecorator = computedDecorator({ equals: comparer.structural }) /** @@ -46,13 +60,15 @@ const computedStructDecorator = computedDecorator({ equals: comparer.structural * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`; */ export var computed: IComputed = function computed(arg1, arg2, arg3) { - if (typeof arg2 === "string" || quacksLikeAStage2Decorator(arguments)) { + debugger + if (typeof arg2 === "string") { // @computed - return computedDecorator.apply(null, arguments) + return classicComputedDecorator.apply(null, arguments) } if (arg1 !== null && typeof arg1 === "object" && arguments.length === 1) { // @computed({ options }) - return computedDecorator.apply(null, arguments) + // @computed get() {} /* stage 2 only *? + return computedDecorator(arg1) } // computed(expr, options?) @@ -71,4 +87,39 @@ export var computed: IComputed = function computed(arg1, arg2, arg3) { return new ComputedValue(opts) } as any +function stage2ComputedDecorator( + options: IComputedValueOptions, + elementDescriptor: Stage2Decorator +): Stage2Decorator { + const { key, descriptor } = elementDescriptor + const { get, set } = descriptor + return { + key, + placement: "prototype", + kind: "method", + descriptor: { + enumerable: false, + configurable: true, + get() { + asObservableObject(this).addComputedProp(this, key, { + get, + set, + context: this, + ...options + }) + return this[key] + }, + set(v) { + asObservableObject(this).addComputedProp(this, key, { + get, + set, + context: this, + ...options + }) + this[key] = v + } + } + } +} + computed.struct = computedStructDecorator From b4b427ca83f5b49207936b530b64909afc7314e4 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 21:57:58 +0200 Subject: [PATCH 11/22] cleaned up @observable implementation --- src/api/computed.ts | 10 +++--- src/api/observabledecorator.ts | 61 ++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/api/computed.ts b/src/api/computed.ts index db55f68f4..d4b5577d0 100644 --- a/src/api/computed.ts +++ b/src/api/computed.ts @@ -19,7 +19,7 @@ export interface IComputed { struct(target: Object, key: string | symbol, baseDescriptor?: PropertyDescriptor): void // decorator } -const classicComputedDecorator = createPropDecorator( +const legacyComputedDecorator = createPropDecorator( false, ( instance: any, @@ -42,14 +42,14 @@ const classicComputedDecorator = createPropDecorator( ) export const computedDecorator = function computedDecorator(arg1) { - if (arguments.length > 1) return classicComputedDecorator.apply(null, arguments) + if (arguments.length > 1) return legacyComputedDecorator.apply(null, arguments) if (quacksLikeAStage2Decorator(arguments)) { return stage2ComputedDecorator(EMPTY_OBJECT, arg1) } return function() { if (quacksLikeAStage2Decorator(arguments)) return stage2ComputedDecorator(arg1, arguments[0]) - else return classicComputedDecorator(arg1).apply(null, arguments) + else return legacyComputedDecorator(arg1).apply(null, arguments) } } @@ -63,7 +63,7 @@ export var computed: IComputed = function computed(arg1, arg2, arg3) { debugger if (typeof arg2 === "string") { // @computed - return classicComputedDecorator.apply(null, arguments) + return legacyComputedDecorator.apply(null, arguments) } if (arg1 !== null && typeof arg1 === "object" && arguments.length === 1) { // @computed({ options }) @@ -95,8 +95,8 @@ function stage2ComputedDecorator( const { get, set } = descriptor return { key, - placement: "prototype", kind: "method", + placement: "prototype", descriptor: { enumerable: false, configurable: true, diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index 0fa5adfb2..b7f918caf 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -7,6 +7,7 @@ import { invariant, quacksLikeAStage2Decorator } from "../internal" +import { Stage2Decorator } from "../utils/decorators" export type IObservableDecorator = { (target: Object, property: string | symbol, descriptor?: PropertyDescriptor): void @@ -15,7 +16,7 @@ export type IObservableDecorator = { export function createDecoratorForEnhancer(enhancer: IEnhancer): IObservableDecorator { invariant(enhancer) - const decorator = createPropDecorator( + const legacyDecorator = createPropDecorator( true, ( target: any, @@ -38,19 +39,53 @@ export function createDecoratorForEnhancer(enhancer: IEnhancer): IObservabl asObservableObject(target).addObservableProp(propertyName, initialValue, enhancer) } ) - const res: any = + const res: any = function observableDecorator() { + if (quacksLikeAStage2Decorator(arguments)) { + return stage2ObservableDecorator(enhancer, arguments[0]) + } // Extra process checks, as this happens during module initialization - typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" - ? function observableDecorator() { - // This wrapper function is just to detect illegal decorator invocations, deprecate in a next version - // and simply return the created prop decorator - if (arguments.length < 2 && !quacksLikeAStage2Decorator(arguments)) - return fail( - "Incorrect decorator invocation. @observable decorator doesn't expect any arguments" - ) - return decorator.apply(null, arguments) - } - : decorator + if ( + process.env.NODE_ENV !== "production" && + arguments.length < 2 && + !quacksLikeAStage2Decorator(arguments) + ) + return fail( + "Incorrect decorator invocation. @observable decorator doesn't expect any arguments" + ) + return legacyDecorator.apply(null, arguments) + } res.enhancer = enhancer return res } + +function stage2ObservableDecorator( + enhancer: IEnhancer, + elementDescriptor: Stage2Decorator +): Stage2Decorator { + const { key, initializer } = elementDescriptor + return { + key, + kind: "method", + placement: "own", // makes sure they are immediately enumerable! + descriptor: { + enumerable: true, + configurable: true, + get() { + asObservableObject(this).addObservableProp( + key, + initializer && initializer.call(this), + enhancer + ) + return this[key] + }, + set(v) { + asObservableObject(this).addObservableProp( + key, + initializer && initializer.call(this), + enhancer + ) + this[key] = v + } + } + } +} From 4503c6eadc03a7fe4560a463fa967876962644b3 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 22:01:56 +0200 Subject: [PATCH 12/22] code cleanup --- src/internal.ts | 1 + src/utils/decorators.ts | 49 +---------------------------------- src/utils/stage2decorators.ts | 12 +++++++++ 3 files changed, 14 insertions(+), 48 deletions(-) create mode 100644 src/utils/stage2decorators.ts diff --git a/src/internal.ts b/src/internal.ts index 1d9b12790..e851507b7 100644 --- a/src/internal.ts +++ b/src/internal.ts @@ -9,6 +9,7 @@ export * from "./utils/utils" export * from "./core/atom" export * from "./utils/comparer" export * from "./utils/decorators" +export * from "./utils/stage2decorators" export * from "./types/modifiers" export * from "./api/observabledecorator" export * from "./api/observable" diff --git a/src/utils/decorators.ts b/src/utils/decorators.ts index f8f38ad0b..ab6232762 100644 --- a/src/utils/decorators.ts +++ b/src/utils/decorators.ts @@ -26,15 +26,6 @@ type DecoratorInvocationDescription = { decoratorArguments: any[] } -export type Stage2Decorator = { - kind: "field" | "method" | "class" - key: string - placement: "static" | "prototype" | "own" - descriptor: PropertyDescriptor - initializer?: () => any - finisher?: (klass) => void -} - const enumerableDescriptorCache: { [prop: string]: PropertyDescriptor } = {} const nonEnumerableDescriptorCache: { [prop: string]: PropertyDescriptor } = {} @@ -88,40 +79,6 @@ export function createPropDecorator( // This is a special parameter to signal the direct application of a decorator, allow extendObservable to skip the entire type decoration part, // as the instance to apply the decorator to equals the target ) { - if (quacksLikeAStage2Decorator(arguments)) { - const stage2decorator = target as Stage2Decorator - const { key, descriptor, initializer } = stage2decorator - return { - kind: "method", - placement: propertyInitiallyEnumerable ? "own" : "prototype", - key, - descriptor: { - enumerable: propertyInitiallyEnumerable, - configurable: true, - get() { - propertyCreator( - this, - key, - { ...descriptor, initializer }, - this, - decoratorArguments - ) - return this[key] - }, - set(v) { - propertyCreator( - this, - key, - { ...descriptor, initializer }, - this, - decoratorArguments - ) - this[key] = v - } - } - } - } - if (applyImmediately === true) { propertyCreator(target, prop, descriptor, target, decoratorArguments) return null @@ -142,7 +99,7 @@ export function createPropDecorator( return createPropertyInitializerDescriptor(prop, propertyInitiallyEnumerable) } - if (quacksLikeADecorator(arguments) || quacksLikeAStage2Decorator(arguments)) { + if (quacksLikeADecorator(arguments)) { // @decorator decoratorArguments = EMPTY_ARRAY return decorator.apply(null, arguments) @@ -160,7 +117,3 @@ export function quacksLikeADecorator(args: IArguments): boolean { (args.length === 4 && args[3] === true) ) } - -export function quacksLikeAStage2Decorator(args: IArguments): boolean { - return args.length === 1 && args[0] && (args[0].kind === "field" || args[0].kind === "method") -} diff --git a/src/utils/stage2decorators.ts b/src/utils/stage2decorators.ts new file mode 100644 index 000000000..e03e8532f --- /dev/null +++ b/src/utils/stage2decorators.ts @@ -0,0 +1,12 @@ +export type Stage2Decorator = { + kind: "field" | "method" | "class" + key: string + placement: "static" | "prototype" | "own" + descriptor: PropertyDescriptor + initializer?: () => any + finisher?: (klass) => void +} + +export function quacksLikeAStage2Decorator(args: IArguments): boolean { + return args.length === 1 && args[0] && (args[0].kind === "field" || args[0].kind === "method") +} From a5818ba6106eb489be6eb44732c72a27b72cef70 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 24 Sep 2018 22:14:06 +0200 Subject: [PATCH 13/22] Some tidy up --- src/api/computed.ts | 9 ++++----- src/api/observabledecorator.ts | 15 ++++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/api/computed.ts b/src/api/computed.ts index d4b5577d0..9e3dbdcd4 100644 --- a/src/api/computed.ts +++ b/src/api/computed.ts @@ -6,10 +6,10 @@ import { comparer, createPropDecorator, invariant, - quacksLikeAStage2Decorator + quacksLikeAStage2Decorator, + Stage2Decorator, + EMPTY_OBJECT } from "../internal" -import { Stage2Decorator } from "../utils/decorators" -import { EMPTY_OBJECT } from "../utils/utils" export interface IComputed { (options: IComputedValueOptions): any // decorator @@ -60,12 +60,11 @@ const computedStructDecorator = computedDecorator({ equals: comparer.structural * For legacy purposes also invokable as ES5 observable created: `computed(() => expr)`; */ export var computed: IComputed = function computed(arg1, arg2, arg3) { - debugger if (typeof arg2 === "string") { // @computed return legacyComputedDecorator.apply(null, arguments) } - if (arg1 !== null && typeof arg1 === "object" && arguments.length === 1) { + if (arguments.length === 1 && typeof arg1 === "object") { // @computed({ options }) // @computed get() {} /* stage 2 only *? return computedDecorator(arg1) diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index b7f918caf..4bf49fc35 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -5,9 +5,9 @@ import { createPropDecorator, fail, invariant, - quacksLikeAStage2Decorator + quacksLikeAStage2Decorator, + Stage2Decorator } from "../internal" -import { Stage2Decorator } from "../utils/decorators" export type IObservableDecorator = { (target: Object, property: string | symbol, descriptor?: PropertyDescriptor): void @@ -43,12 +43,7 @@ export function createDecoratorForEnhancer(enhancer: IEnhancer): IObservabl if (quacksLikeAStage2Decorator(arguments)) { return stage2ObservableDecorator(enhancer, arguments[0]) } - // Extra process checks, as this happens during module initialization - if ( - process.env.NODE_ENV !== "production" && - arguments.length < 2 && - !quacksLikeAStage2Decorator(arguments) - ) + if (process.env.NODE_ENV !== "production" && arguments.length < 2) return fail( "Incorrect decorator invocation. @observable decorator doesn't expect any arguments" ) @@ -66,7 +61,9 @@ function stage2ObservableDecorator( return { key, kind: "method", - placement: "own", // makes sure they are immediately enumerable! + // makes sure they are immediately enumerable! + // ideally we would put it in the prototype, but then the props are not immediately visible on the instance (through Object.keys and such) + placement: "own", descriptor: { enumerable: true, configurable: true, From 3cbcfb51c6e6a38492e1ca66b410c920b6069665 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 08:49:12 +0200 Subject: [PATCH 14/22] Found work around for late initialization --- src/api/observabledecorator.ts | 36 ++++++++++++++-------------------- test/base/babel-tests.js | 4 ++-- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index 4bf49fc35..83eb2fb76 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -58,31 +58,25 @@ function stage2ObservableDecorator( elementDescriptor: Stage2Decorator ): Stage2Decorator { const { key, initializer } = elementDescriptor + // This property is basically an ugly hack + // To run some code upon initialization, + // see: https://github.com/tc39/proposal-decorators/issues/153 return { - key, - kind: "method", - // makes sure they are immediately enumerable! - // ideally we would put it in the prototype, but then the props are not immediately visible on the instance (through Object.keys and such) + key: key + "_initializer", + kind: "field", placement: "own", descriptor: { - enumerable: true, + enumerable: false, configurable: true, - get() { - asObservableObject(this).addObservableProp( - key, - initializer && initializer.call(this), - enhancer - ) - return this[key] - }, - set(v) { - asObservableObject(this).addObservableProp( - key, - initializer && initializer.call(this), - enhancer - ) - this[key] = v - } + writable: true + }, + initializer() { + asObservableObject(this).addObservableProp( + key, + initializer && initializer.call(this), + enhancer + ) + return undefined } } } diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 69c0f3285..c4950cbd4 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -140,8 +140,8 @@ class Order { test("decorators", function() { var o = new Order() // Broken, see: https://github.com/tc39/proposal-decorators/issues/153 - // expect(isObservableObject(o)).toBe(true) - // expect(isObservableProp(o, "amount")).toBe(true) + expect(isObservableObject(o)).toBe(true) + expect(isObservableProp(o, "amount")).toBe(true) expect(o.total).toBe(6) // .... this is required to initialize the props which are made reactive lazily... expect(isObservableProp(o, "total")).toBe(true) From 1c7093a6546f0a20d9aa12a1db0c269ed7ffc69b Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 09:17:33 +0200 Subject: [PATCH 15/22] Introduced better work-around for lazy observable initialization --- src/api/observabledecorator.ts | 51 +++++++++++++++++++++------------- src/types/observableobject.ts | 16 +++++++---- src/utils/stage2decorators.ts | 1 + test/base/babel-tests.js | 11 +++++++- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index 83eb2fb76..ab094c883 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -6,7 +6,8 @@ import { fail, invariant, quacksLikeAStage2Decorator, - Stage2Decorator + Stage2Decorator, + generateObservablePropConfig } from "../internal" export type IObservableDecorator = { @@ -58,25 +59,37 @@ function stage2ObservableDecorator( elementDescriptor: Stage2Decorator ): Stage2Decorator { const { key, initializer } = elementDescriptor - // This property is basically an ugly hack - // To run some code upon initialization, - // see: https://github.com/tc39/proposal-decorators/issues/153 return { - key: key + "_initializer", - kind: "field", + key, + kind: "method", placement: "own", - descriptor: { - enumerable: false, - configurable: true, - writable: true - }, - initializer() { - asObservableObject(this).addObservableProp( - key, - initializer && initializer.call(this), - enhancer - ) - return undefined - } + initializer: undefined, + descriptor: generateObservablePropConfig(key), + extras: [ + // introduce an additional property that is always undefined, + // just to be able to rn initialization code upon instance creation + // This property is basically an ugly hack + // To run some code upon initialization, + // see: https://github.com/tc39/proposal-decorators/issues/153 + { + key: "__mobx-initializer-" + key, + kind: "field", + placement: "own", + descriptor: { + enumerable: false, + configurable: true, + writable: true + }, + initializer() { + asObservableObject(this).initializeObservableProp( + key, + initializer && initializer.call(this), + enhancer + ) + // rather, we would want to delete this property... + return undefined + } + } + ] } } diff --git a/src/types/observableobject.ts b/src/types/observableobject.ts index 282990f69..05974224f 100644 --- a/src/types/observableobject.ts +++ b/src/types/observableobject.ts @@ -174,6 +174,13 @@ export class ObservableObjectAdministration if (!change) return newValue = (change as any).newValue } + + Object.defineProperty(target, propName, generateObservablePropConfig(propName)) + newValue = this.initializeObservableProp(propName, newValue, enhancer) + this.notifyPropertyAddition(propName, newValue) + } + + initializeObservableProp(propName: string, newValue, enhancer: IEnhancer) { const observable = new ObservableValue( newValue, enhancer, @@ -181,10 +188,7 @@ export class ObservableObjectAdministration false ) this.values.set(propName, observable) - newValue = (observable as any).value // observableValue might have changed it - - Object.defineProperty(target, propName, generateObservablePropConfig(propName)) - this.notifyPropertyAddition(propName, newValue) + return (observable as any).value // observableValue might have changed it } addComputedProp( @@ -339,8 +343,8 @@ export function asObservableObject( return adm } -const observablePropertyConfigs = Object.create(null); -const computedPropertyConfigs = Object.create(null); +const observablePropertyConfigs = Object.create(null) +const computedPropertyConfigs = Object.create(null) export function generateObservablePropConfig(propName) { return ( diff --git a/src/utils/stage2decorators.ts b/src/utils/stage2decorators.ts index e03e8532f..ea9695a05 100644 --- a/src/utils/stage2decorators.ts +++ b/src/utils/stage2decorators.ts @@ -5,6 +5,7 @@ export type Stage2Decorator = { descriptor: PropertyDescriptor initializer?: () => any finisher?: (klass) => void + extras?: Stage2Decorator[] } export function quacksLikeAStage2Decorator(args: IArguments): boolean { diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index c4950cbd4..141b8afc9 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -442,7 +442,7 @@ test("288 atom not detected for object property", () => { expect(changed).toBe(true) }) -test.skip("observable performance", () => { +test("observable performance", () => { const AMOUNT = 100000 class A { @@ -624,6 +624,15 @@ test("enumerability", () => { expect(a.hasOwnProperty("b")).toBe(true) // ideally, false. see: #1398 expect(a.hasOwnProperty("m")).toBe(false) expect(a.hasOwnProperty("m2")).toBe(true) + + expect(Object.getOwnPropertyNames(a)).toEqual([ + "a", + "a2", + "__mobx-initializer-a", // Yikes! https://github.com/tc39/proposal-decorators/issues/153 + "__mobx-initializer-a2", + "m2", + "b" + ]) }) test("enumerability - workaround", () => { From 1bcb4a9207bb396bae92a49fd470964c435a9594 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 09:29:23 +0200 Subject: [PATCH 16/22] Disabled perf test --- test/base/babel-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 141b8afc9..7d69ff585 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -442,7 +442,7 @@ test("288 atom not detected for object property", () => { expect(changed).toBe(true) }) -test("observable performance", () => { +test.only("observable performance", () => { const AMOUNT = 100000 class A { From ac3d2ef39c44ddc1847243e9c3a56036497ab50d Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 09:33:54 +0200 Subject: [PATCH 17/22] Added TODO about using stage2 impl for decorate / extendobservable in the future as well --- src/api/decorate.ts | 1 + src/api/extendobservable.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/api/decorate.ts b/src/api/decorate.ts index fad6e4705..460c3f311 100644 --- a/src/api/decorate.ts +++ b/src/api/decorate.ts @@ -39,6 +39,7 @@ export function decorate(thing: any, decorators: any) { (accDescriptor, decorator) => decorator(target, prop, accDescriptor), descriptor ) + // TODO: in future, use the stage2 definitions / implementations instead if (newDescriptor) Object.defineProperty(target, prop, newDescriptor) } return thing diff --git a/src/api/extendobservable.ts b/src/api/extendobservable.ts index e0a281159..815f7f19e 100644 --- a/src/api/extendobservable.ts +++ b/src/api/extendobservable.ts @@ -89,6 +89,7 @@ export function extendObservableObjectWithProperties( if (process.env.NODE_ENV !== "production" && typeof decorator !== "function") fail(`Not a valid decorator for '${key}', got: ${decorator}`) + // TODO: in future, use the stage2 definitions / implementations instead const resultDescriptor = decorator!(target, key, descriptor, true) if ( resultDescriptor // otherwise, assume already applied, due to `applyToInstance` From 6092288297c0cc596064c555ec4203c5c57f5a94 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 10:27:05 +0200 Subject: [PATCH 18/22] Updated Changelog --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ test/base/babel-tests.js | 3 ++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8abcc6b6a..97482e0ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +# 5.5.0 / 4.5.0 + +(Jumped minor version of 5 to have the numbers more closely aligned) + +MobX now supports 4 different implementations of the decorators proposal: +* TypeScript with the `--experimentalDecorators` compiler flag enabled +* Babel 6, trough the `babel-plugin-transform-decorators-legacy` plugin +* Babel 7, with `@babel/plugin-proposal-decorators` in legacy mode. (Setting: `legacy: true`) +* **🎉NEW🎉** Babel 7, with `@babel/plugin-proposal-decorators` in stage 2 spec mode. (Setting: `legacy: false`) + +Because these implementations offer different features and semantics, there are subtle differences in all implementations. +They won't affect 99% of your work, but sometimes there are subtle differences. + +These are the changes introduced by the Babel 7 implementation *if* `legacy` is set to `false`: + +* The legacy decorators issue where fields were not initialized until the first read are solved. +* The exception is computed properties, running `isComputedProp` on an `@computed` decorated field that was never accessed will incorrectly yield `false`. ([background](https://github.com/tc39/proposal-decorators/issues/153)) +* There is a [babel issue](https://github.com/babel/babel/issues/8760), which has been fixed but not released yet, which causes non-decorated fields to be no longer enumerable. This currently breaks utilities like `toJS`, however this is not a MobX issue and should resolve itself with the next Babel release. +* Computed properties become now live on the instance, rather than the prototype, so they become part of the _ownProperties_ of an object. However, they are still not enumerable, so this should make no difference in practice. +* MobX generates non-enumerable utility properties that are all of the form `__mobx-initializer-${propName}`. Those always have the value `undefined` and you can even delete them if they annoy you, but those were introduced to work around some limitations of the current stage2 proposal ([background](https://github.com/tc39/proposal-decorators/issues/153)) +* By supporting the stage2 implementation, it is now possible to use `@babel/plugin-proposal-class-properties` in spec mode (that is, with option: `{ "loose": false }`). However, the `spec` mode breaks using the `decorate` utility on class instances, so for now it is recommended to keep using `{ "loose": true }` in your babel configuration +* The value of te `decoratorsBeforeExport` setting of `plugin-proposal-decorators` is technically indifferent to MobX, but it is recommended to set it to `true`, this is in line with the legacy syntax and all current MobX documentation. With `true`, one can write: `@observer export class MyComponent extends React.Component {...`, with `false`, this needs to be rewritten as: `export @ observer class MyComponent extends React.Component {...`. ([background](https://github.com/tc39/proposal-decorators/issues/69)) + +In summary: this is the babel config that uses the stage2 decorators implementation: + +```json +{ + "plugins": [ + ["@babel/plugin-proposal-decorators", { "legacy": false, "decoratorsBeforeExport": true }], + ["@babel/plugin-proposal-class-properties", { "loose": true }] + ] +} +``` + # 5.1.2 / 4.4.2 * Fixed [#1650](https://github.com/mobxjs/mobx/issues/1650), decorating fields with the name `toString` does not behave correctly. diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index 7d69ff585..52ef03fd3 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -142,6 +142,7 @@ test("decorators", function() { // Broken, see: https://github.com/tc39/proposal-decorators/issues/153 expect(isObservableObject(o)).toBe(true) expect(isObservableProp(o, "amount")).toBe(true) + expect(isComputedProp(o, "total")).toBe(false) // Should be true expect(o.total).toBe(6) // .... this is required to initialize the props which are made reactive lazily... expect(isObservableProp(o, "total")).toBe(true) @@ -442,7 +443,7 @@ test("288 atom not detected for object property", () => { expect(changed).toBe(true) }) -test.only("observable performance", () => { +test.skip("observable performance", () => { const AMOUNT = 100000 class A { From 2ef73472434bab633b8f2517a7c7e441db47f6d7 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Tue, 25 Sep 2018 16:47:21 +0200 Subject: [PATCH 19/22] fixed typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97482e0ac..e21ff8342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ These are the changes introduced by the Babel 7 implementation *if* `legacy` is * Computed properties become now live on the instance, rather than the prototype, so they become part of the _ownProperties_ of an object. However, they are still not enumerable, so this should make no difference in practice. * MobX generates non-enumerable utility properties that are all of the form `__mobx-initializer-${propName}`. Those always have the value `undefined` and you can even delete them if they annoy you, but those were introduced to work around some limitations of the current stage2 proposal ([background](https://github.com/tc39/proposal-decorators/issues/153)) * By supporting the stage2 implementation, it is now possible to use `@babel/plugin-proposal-class-properties` in spec mode (that is, with option: `{ "loose": false }`). However, the `spec` mode breaks using the `decorate` utility on class instances, so for now it is recommended to keep using `{ "loose": true }` in your babel configuration -* The value of te `decoratorsBeforeExport` setting of `plugin-proposal-decorators` is technically indifferent to MobX, but it is recommended to set it to `true`, this is in line with the legacy syntax and all current MobX documentation. With `true`, one can write: `@observer export class MyComponent extends React.Component {...`, with `false`, this needs to be rewritten as: `export @ observer class MyComponent extends React.Component {...`. ([background](https://github.com/tc39/proposal-decorators/issues/69)) +* The value of te `decoratorsBeforeExport` setting of `plugin-proposal-decorators` is technically indifferent to MobX, but it is recommended to set it to `true`, this is in line with the legacy syntax and all current MobX documentation. With `true`, one can write: `@observer export class MyComponent extends React.Component {...`, with `false`, this needs to be rewritten as: `export @observer class MyComponent extends React.Component {...`. ([background](https://github.com/tc39/proposal-decorators/issues/69)) In summary: this is the babel config that uses the stage2 decorators implementation: From 23d245eabb6397ae783d5182d2351849aaddd794 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Sat, 2 Feb 2019 23:23:50 +0100 Subject: [PATCH 20/22] Upgraded to Babel 7.3.0 --- package.json | 8 +- src/api/actiondecorator.ts | 4 + test/base/babel-tests.js | 7 +- yarn.lock | 722 ++++++++++++++++++++++++++----------- 4 files changed, 532 insertions(+), 209 deletions(-) diff --git a/package.json b/package.json index fc87b5ef4..a6533da18 100644 --- a/package.json +++ b/package.json @@ -46,10 +46,10 @@ ], "homepage": "https://mobx.js.org/", "devDependencies": { - "@babel/core": "^7.1.0", - "@babel/plugin-proposal-class-properties": "^7.1.0", - "@babel/plugin-proposal-decorators": "^7.1.0", - "@babel/preset-env": "^7.1.0", + "@babel/core": "^7.3.0", + "@babel/plugin-proposal-class-properties": "^7.3.0", + "@babel/plugin-proposal-decorators": "^7.3.0", + "@babel/preset-env": "^7.3.0", "@types/jest": "^21.1.9", "@types/node": "^7.0.22", "babel-core": "^7.0.0-bridge.0", diff --git a/src/api/actiondecorator.ts b/src/api/actiondecorator.ts index 9b428f522..508a59107 100644 --- a/src/api/actiondecorator.ts +++ b/src/api/actiondecorator.ts @@ -71,6 +71,10 @@ export function stage2NamedActionDecorator( // @action.bound method = () => {} return { ...elementDescriptor, + descriptor: { + ...descriptor, + enumerable: false // fields are by default enumerable, be we don't like enumerable actions + }, initializer() { return createAction(name, elementDescriptor.initializer!.call(this)) } diff --git a/test/base/babel-tests.js b/test/base/babel-tests.js index f33d73a87..4820b7225 100644 --- a/test/base/babel-tests.js +++ b/test/base/babel-tests.js @@ -675,7 +675,7 @@ test("enumerability - workaround", () => { expect(a.hasOwnProperty("m2")).toBe(true) }) -test.skip("Babel bug", () => { +test("Babel bug", () => { // See: https://github.com/babel/babel/issues/8760 class Todo1 { id = 1 @@ -693,7 +693,7 @@ test.skip("Babel bug", () => { expect(Object.getOwnPropertyDescriptor(t1, "id").enumerable).toBe(true) const t2 = new Todo2() - expect(Object.getOwnPropertyDescriptor(t2, "id").enumerable).toBe(true) // fails + expect(Object.getOwnPropertyDescriptor(t2, "id").enumerable).toBe(true) }) test("issue 285 (babel)", () => { @@ -715,7 +715,7 @@ test("issue 285 (babel)", () => { const res = toJS(todo) expect(res).toEqual({ - // TODO: should inclue id: 1 // Babel 7 bug, see https://github.com/babel/babel/issues/8760 + id: 1, title: "Something to do", finished: false, childThings: [1, 2, 3] @@ -1201,7 +1201,6 @@ test("computed setter problem - 2", () => { } } - debugger mobx.decorate(Contact, { fullName: computed({ // This doesn't work diff --git a/yarn.lock b/yarn.lock index c21457e29..7add949b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,20 +14,21 @@ dependencies: "@babel/highlight" "7.0.0-beta.48" -"@babel/core@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.0.tgz#08958f1371179f62df6966d8a614003d11faeb04" +"@babel/core@^7.3.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" + integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/helpers" "^7.1.0" - "@babel/parser" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.2.2" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.2.2" + "@babel/types" "^7.2.2" convert-source-map "^1.1.0" - debug "^3.1.0" - json5 "^0.5.0" + debug "^4.1.0" + json5 "^2.1.0" lodash "^4.17.10" resolve "^1.3.2" semver "^5.4.1" @@ -43,6 +44,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.2.2": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.0.tgz#f663838cd7b542366de3aa608a657b8ccb2a99eb" + integrity sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg== + dependencies: + "@babel/types" "^7.3.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -64,6 +76,17 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-create-class-features-plugin@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.0.tgz#2b01a81b3adc2b1287f9ee193688ef8dc71e718f" + integrity sha512-DUsQNS2CGLZZ7I3W3fvh0YpPDd6BuWJlDl+qmZZpABZHza2ErE3LxtEzLJFHFC1ZwtlAXvHhbFYbtM5o5B0WBw== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.2.3" + "@babel/helper-define-map@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" @@ -157,6 +180,16 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-replace-supers@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5" + integrity sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.2.3" + "@babel/types" "^7.0.0" + "@babel/helper-simple-access@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" @@ -179,13 +212,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helpers@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.0.tgz#429bf0f0020be56a4242883432084e3d70a8a141" +"@babel/helpers@^7.2.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" + integrity sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA== dependencies: - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.5" + "@babel/types" "^7.3.0" "@babel/highlight@7.0.0-beta.48": version "7.0.0-beta.48" @@ -207,129 +241,140 @@ version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.0.tgz#a7cd42cb3c12aec52e24375189a47b39759b783e" -"@babel/plugin-proposal-async-generator-functions@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" +"@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.1.tgz#8f4ffd45f779e6132780835ffa7a215fa0b2d181" + integrity sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" -"@babel/plugin-proposal-class-properties@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4" +"@babel/plugin-proposal-class-properties@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.0.tgz#272636bc0fa19a0bc46e601ec78136a173ea36cd" + integrity sha512-wNHxLkEKTQ2ay0tnsam2z7fGZUi+05ziDJflEt3AZTP3oXLKHJp9HqhfroB/vdMvt3sda9fAbq7FsG8QPDrZBg== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-create-class-features-plugin" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" -"@babel/plugin-proposal-decorators@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.1.0.tgz#bb39ae934318e4560db2d724b0fca8da0299b120" +"@babel/plugin-proposal-decorators@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.3.0.tgz#637ba075fa780b1f75d08186e8fb4357d03a72a7" + integrity sha512-3W/oCUmsO43FmZIqermmq6TKaRSYhmh/vybPfVFwQWdSb8xwki38uAIvknCRzuyHRuYfCYmJzL9or1v0AffPjg== dependencies: + "@babel/helper-create-class-features-plugin" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/plugin-syntax-decorators" "^7.1.0" + "@babel/plugin-syntax-decorators" "^7.2.0" -"@babel/plugin-proposal-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" +"@babel/plugin-proposal-object-rest-spread@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.1.tgz#f69fb6a1ea6a4e1c503994a91d9cf76f3c4b36e8" + integrity sha512-Nmmv1+3LqxJu/V5jU9vJmxR/KIRWFk2qLHmbB56yRRRFhlaSuOVXscX3gUmhaKgUhzA3otOHVubbIEVYsZ0eZg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" +"@babel/plugin-proposal-unicode-property-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" + integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.2.0" -"@babel/plugin-syntax-async-generators@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-class-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" +"@babel/plugin-syntax-decorators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz#c50b1b957dcc69e4b1127b65e1c33eef61570c1b" + integrity sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-decorators@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.1.0.tgz#2fa7c1a7905a299c9853ebcef340306675f9cbdc" +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" +"@babel/plugin-transform-async-to-generator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" + integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz#1745075edffd7cdaf69fab2fb6f9694424b7e9bc" +"@babel/plugin-transform-block-scoping@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" -"@babel/plugin-transform-classes@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" +"@babel/plugin-transform-classes@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953" + integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -340,103 +385,124 @@ "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0.tgz#68e911e1935dda2f06b6ccbbf184ffb024e9d43a" +"@babel/plugin-transform-destructuring@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" + integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/plugin-transform-duplicate-keys@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" +"@babel/plugin-transform-for-of@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" +"@babel/plugin-transform-function-name@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-commonjs@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" +"@babel/plugin-transform-modules-commonjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0.tgz#8873d876d4fee23209decc4d1feab8f198cf2df4" +"@babel/plugin-transform-modules-systemjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" + integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-umd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz#140b52985b2d6ef0cb092ef3b29502b990f9cd50" + integrity sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw== + dependencies: + regexp-tree "^0.1.0" + "@babel/plugin-transform-new-target@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.1.0" -"@babel/plugin-transform-parameters@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" +"@babel/plugin-transform-parameters@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" @@ -448,88 +514,97 @@ dependencies: regenerator-transform "^0.13.3" -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/preset-env@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.0.tgz#e67ea5b0441cfeab1d6f41e9b5c79798800e8d11" +"@babel/preset-env@^7.3.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" + integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.1.0" - "@babel/plugin-proposal-json-strings" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.1.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.1.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-dotall-regex" "^7.0.0" - "@babel/plugin-transform-duplicate-keys" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.1.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.1.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-amd" "^7.1.0" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" - "@babel/plugin-transform-modules-systemjs" "^7.0.0" - "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.3.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.2.0" + "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.2.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" "@babel/plugin-transform-new-target" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.1.0" - "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.2.0" "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typeof-symbol" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - browserslist "^4.1.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + browserslist "^4.3.4" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.3.0" @@ -542,6 +617,15 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/template@^7.1.2", "@babel/template@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" + "@babel/traverse@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2" @@ -556,6 +640,21 @@ globals "^11.1.0" lodash "^4.17.10" +"@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + "@babel/types@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118" @@ -564,6 +663,15 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@babel/types@^7.2.2", "@babel/types@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.0.tgz#61dc0b336a93badc02bf5f69c4cd8e1353f2ffc0" + integrity sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@types/jest@^21.1.9": version "21.1.10" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-21.1.10.tgz#dcacb5217ddf997a090cc822bba219b4b2fd7984" @@ -1436,13 +1544,14 @@ browserify@^12.0.1: vm-browserify "~0.0.1" xtend "^4.0.0" -browserslist@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.1.1.tgz#328eb4ff1215b12df6589e9ab82f8adaa4fc8cd6" +browserslist@^4.3.4: + version "4.4.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.4.1.tgz#42e828954b6b29a7a53e352277be429478a69062" + integrity sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A== dependencies: - caniuse-lite "^1.0.30000884" - electron-to-chromium "^1.3.62" - node-releases "^1.0.0-alpha.11" + caniuse-lite "^1.0.30000929" + electron-to-chromium "^1.3.103" + node-releases "^1.1.3" bser@^2.0.0: version "2.0.0" @@ -1524,9 +1633,15 @@ camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -caniuse-lite@^1.0.30000884: - version "1.0.30000885" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000885.tgz#e889e9f8e7e50e769f2a49634c932b8aee622984" +camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +caniuse-lite@^1.0.30000929: + version "1.0.30000933" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000933.tgz#5871ff54b3177675ae1c2a275b2aae7abf2b9222" + integrity sha512-d3QXv7eFTU40DSedSP81dV/ajcGSKpT+GW+uhtWmLvQm9bPk0KK++7i1e2NSW/CXGZhWFt2mFbFtCJ5I5bMuVA== capture-exit@^1.2.0: version "1.2.0" @@ -1619,6 +1734,16 @@ cli-spinners@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" +cli-table3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" @@ -1848,6 +1973,17 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1941,9 +2077,17 @@ debug@^3.1.0: dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1: +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decode-uri-component@^0.2.0: version "0.2.0" @@ -2102,9 +2246,10 @@ ejs@^2.5.6: version "2.5.6" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88" -electron-to-chromium@^1.3.62: - version "1.3.70" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.70.tgz#ded377256d92d81b4257d36c65aa890274afcfd2" +electron-to-chromium@^1.3.103: + version "1.3.112" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.112.tgz#1f40a68ceda6328f95218dffeda0f4f3d5412a2f" + integrity sha512-FyVLdiRZnLw2WE5ECtveN0JJ7klyiz/HMfKE1/Rjff3l7pe4vfkYtBlcCqTckvR8E7asjJGh0m9gRPR3Anp/UA== elegant-spinner@^1.0.1: version "1.0.1" @@ -2130,6 +2275,13 @@ encodeurl@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + enhanced-resolve@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.3.0.tgz#950964ecc7f0332a42321b673b38dc8ff15535b3" @@ -2322,6 +2474,19 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" @@ -2549,6 +2714,13 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + flow-bin@^0.59.0: version "0.59.0" resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.59.0.tgz#8c151ee7f09f1deed9bf0b9d1f2e8ab9d470f1bb" @@ -2675,6 +2847,13 @@ get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -3028,6 +3207,11 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + ipaddr.js@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" @@ -3888,6 +4072,13 @@ json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + jsonfile@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" @@ -3963,6 +4154,13 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" @@ -4087,6 +4285,14 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + lodash._baseindexof@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" @@ -4182,6 +4388,13 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -4206,6 +4419,15 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" +mem@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.1.0.tgz#aeb9be2d21f47e78af29e4ac5978e8afa2ca5b8a" + integrity sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^2.0.0" + memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -4378,6 +4600,11 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -4419,6 +4646,11 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4475,9 +4707,10 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.0.0-alpha.11: - version "1.0.0-alpha.11" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.11.tgz#73c810acc2e5b741a17ddfbb39dfca9ab9359d8a" +node-releases@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.7.tgz#b09a10394d0ed8f7778f72bb861dde68b146303b" + integrity sha512-bKdrwaqJUPHqlCzDD7so/R+Nk0jGv9a11ZhLrD9f6i947qGLrGAhU3OxRENa19QQmwzGy/g6zCDEuLGDO8HPvA== dependencies: semver "^5.3.0" @@ -4611,9 +4844,10 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" @@ -4678,6 +4912,15 @@ os-locale@^2.0.0: lcid "^1.0.0" mem "^1.1.0" +os-locale@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -4689,22 +4932,46 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-is-promise@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.0.0.tgz#7554e3d572109a87e1f3f53f6a7d85d1b194f4c5" + integrity sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg== + p-limit@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.1.0.tgz#1d5a0d20fb12707c758a655f6bbc4386b5930d68" + integrity sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g== + dependencies: + p-try "^2.0.0" + p-locate@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-map@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.1.1.tgz#05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a" @@ -4713,6 +4980,11 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + pako@~0.2.0: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" @@ -4778,7 +5050,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -4925,6 +5197,14 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -5126,6 +5406,15 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp-tree@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.1.tgz#27b455f9b138ca2e84c090e9aff1ffe2a04d97fa" + integrity sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw== + dependencies: + cli-table3 "^0.5.0" + colors "^1.1.2" + yargs "^12.0.5" + regexpu-core@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.1.3.tgz#fb81616dbbc2a917a7419b33f8379144f51eb8d0" @@ -6434,6 +6723,11 @@ y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" +"y18n@^3.2.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -6442,6 +6736,14 @@ yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" @@ -6477,6 +6779,24 @@ yargs@^11.0.0: y18n "^3.2.1" yargs-parser "^9.0.2" +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + yargs@^6.0.0: version "6.6.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" From 93a81e3d4e8f48ff621696fc4419602de730274c Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Sun, 3 Feb 2019 00:05:00 +0100 Subject: [PATCH 21/22] WIP: use hooks from the proposal --- src/api/observabledecorator.ts | 10 ++-------- src/utils/stage2decorators.ts | 6 +++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/api/observabledecorator.ts b/src/api/observabledecorator.ts index ab094c883..58e76feb4 100644 --- a/src/api/observabledecorator.ts +++ b/src/api/observabledecorator.ts @@ -72,17 +72,11 @@ function stage2ObservableDecorator( // To run some code upon initialization, // see: https://github.com/tc39/proposal-decorators/issues/153 { - key: "__mobx-initializer-" + key, - kind: "field", + kind: "hook", placement: "own", - descriptor: { - enumerable: false, - configurable: true, - writable: true - }, initializer() { asObservableObject(this).initializeObservableProp( - key, + key!, initializer && initializer.call(this), enhancer ) diff --git a/src/utils/stage2decorators.ts b/src/utils/stage2decorators.ts index ea9695a05..a4a266ae3 100644 --- a/src/utils/stage2decorators.ts +++ b/src/utils/stage2decorators.ts @@ -1,8 +1,8 @@ export type Stage2Decorator = { - kind: "field" | "method" | "class" - key: string + kind: "field" | "method" | "class" | "hook" + key?: string placement: "static" | "prototype" | "own" - descriptor: PropertyDescriptor + descriptor?: PropertyDescriptor initializer?: () => any finisher?: (klass) => void extras?: Stage2Decorator[] From 9d88fdf90ddd07e98b9f2bd0442123039b2c79d2 Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Mon, 4 Feb 2019 14:12:51 +0100 Subject: [PATCH 22/22] Added codefirst to the sponsors list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d37bea518..96b746318 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ MobX is proudly sponsored by Mendix, Coinbase, Facebook Open Source, Canva, Algo Auction Frontier mantro GmbH talentplot +CodeFirst # Installation