From 2fdaaf116152b0c8b90e506900ac187569e7d2b0 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Sat, 2 Jun 2018 15:03:54 +0200 Subject: [PATCH] Initial version --- .babelrc | 2 +- __tests__/__snapshots__/index-test.js.snap | 35 ++++ __tests__/index-test.js | 187 ++++++++++++--------- package.json | 15 +- src/index.js | 67 ++++++-- src/invariant.js | 5 - src/isImmutable.js | 23 +++ src/message-queue.js | 28 --- src/pid.js | 22 --- src/process.js | 47 ------ yarn.lock | 179 ++++++++++++++++++-- 11 files changed, 388 insertions(+), 222 deletions(-) create mode 100644 __tests__/__snapshots__/index-test.js.snap delete mode 100644 src/invariant.js create mode 100644 src/isImmutable.js delete mode 100644 src/message-queue.js delete mode 100644 src/pid.js delete mode 100644 src/process.js diff --git a/.babelrc b/.babelrc index 002b4aa..4ffef06 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["env"] + "presets": ["env", "react"] } diff --git a/__tests__/__snapshots__/index-test.js.snap b/__tests__/__snapshots__/index-test.js.snap new file mode 100644 index 0000000..ba9a5b2 --- /dev/null +++ b/__tests__/__snapshots__/index-test.js.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ReComponent with Immutable.JS records increases the counter when clicked 1`] = ` + +`; + +exports[`ReComponent with Immutable.JS records renders the initial state 1`] = ` + +`; + +exports[`ReComponent with mocked console errors when no \`reducer\` method is defined 1`] = `"Example(...): No \`reducer\` method found on the returned component instance: did you define a reducer?"`; + +exports[`ReComponent with plain JS objects increases the counter when clicked 1`] = ` + +`; + +exports[`ReComponent with plain JS objects renders the initial state 1`] = ` + +`; diff --git a/__tests__/index-test.js b/__tests__/index-test.js index f89c4fa..f79ada1 100644 --- a/__tests__/index-test.js +++ b/__tests__/index-test.js @@ -1,96 +1,117 @@ -import { PID, spawn, isAlive, self, receive, send } from "../"; +import React from "react"; +import ReactDOM from "react-dom"; +import { Record } from "immutable"; -describe("process", () => { - describe("spawn", () => { - it("runs the process", done => { - spawn(function* () { done() }); +import { ReComponent } from "../"; + +global.__DEV__ = true; + +function click(element) { + element.dispatchEvent(new Event("click", { bubbles: true })); +} + +describe("ReComponent", () => { + let container; + beforeEach(() => { + container = document.createElement("div"); + document.body.appendChild(container); + }); + + describe("with plain JS objects", () => { + class Example extends ReComponent { + constructor() { + super(); + this.handleClick = this.createDispatcher("CLICK"); + } + + initialState(props) { + return { + count: 0 + }; + } + + reducer(action, state) { + switch (action.type) { + case "CLICK": + return { count: state.count + 1 }; + } + } + + render() { + return ( + + ); + } + } + + it("renders the initial state", () => { + const instance = ReactDOM.render(, container); + expect(container.firstChild).toMatchSnapshot(); }); - it("returns a pid", () => { - const pid = spawn(function* () {}); - expect(pid).toBeInstanceOf(PID); + it("increases the counter when clicked", () => { + const instance = ReactDOM.render(, container); + click(container.firstChild); + expect(container.firstChild).toMatchSnapshot(); }); }); - describe("isAlive", () => { - it("returns true for another process", () => { - const pid = spawn(function* () { return }); - expect(isAlive(pid)).toBe(true); + describe("with Immutable.JS records", () => { + const State = Record({ count: 0 }); + class Example extends ReComponent { + constructor() { + super(); + this.handleClick = this.createDispatcher("CLICK"); + } + + initialState(props) { + return State(); + } + + reducer(action, state) { + switch (action.type) { + case "CLICK": + return state.update("count", count => count + 1); + } + } + + render() { + return ( + + ); + } + } + + it("renders the initial state", () => { + const instance = ReactDOM.render(, container); + expect(container.firstChild).toMatchSnapshot(); }); - }); - describe("send and receive", () => { - it("can receive a messages on the main process that was already sent", async () => { - send(self(), { - type: "test", - payload: { key: "value" } - }); - - const message = await receive("test"); - expect(message).toEqual({ - type: "test", - payload: { key: "value" } - }); + it("increases the counter when clicked", () => { + const instance = ReactDOM.render(, container); + click(container.firstChild); + expect(container.firstChild).toMatchSnapshot(); }); + }); - it("can receive a messages on the main process that will be sent", async () => { - setTimeout(() => { - send(self(), { - type: "test", - payload: { key: "value" } - }); - }, 0); - - const message = await receive("test"); - expect(message).toEqual({ - type: "test", - payload: { key: "value" } - }); + describe("with mocked console", () => { + const originalError = console.error; + beforeEach(() => (console.error = jest.fn())); + afterEach(() => (console.error = originalError)); + it("errors when no `reducer` method is defined", () => { + class Example extends ReComponent { + render() { + return
; + } + } + + expect(() => { + ReactDOM.render(, container); + }).toThrowErrorMatchingSnapshot(); }); }); }); - -// class CountServer extends GenServer { -// getInitialState(initialProps) { -// this.state = { counter: initialProps.counter || 0 } -// } - -// // async -// handleCast(action) { -// switch (action.type) { -// case "INCREMENT": -// this.setState(({ count }) => { -// count: count + 1; -// }); -// break; -// case "DECREMENT": -// this.setState(({ count }) => { -// count: count - 1; -// }); -// break; -// } -// } - -// // sync -// handleCall(action) { -// switch (action.type) { -// case "INCREMENT": -// this.setState(({ count }) => { -// count: count + 1; -// }); -// break; -// case "DECREMENT": -// this.setState(({ count }) => { -// count: count - 1; -// }); -// break; -// } -// } -// } -// -// describe("react-genserver", () => { -// it("works", () => { -// const pid = start(CountServer) -// console.log(pid); -// }); -// }); diff --git a/package.json b/package.json index 07745a6..be0a840 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,20 @@ { - "name": "react-genserver", - "version": "1.0.0", + "name": "react-recomponent", + "version": "0.0.1", "main": "src/index.js", "license": "MIT", "devDependencies": { "babel-core": "^6.26.3", "babel-jest": "^23.0.1", "babel-preset-env": "^1.7.0", + "babel-preset-react": "^6.24.1", "jest": "^23.1.0", - "prettier": "^1.13.4" + "prettier": "^1.13.4", + "react": "^16.4.0", + "react-dom": "^16.4.0", + "react-test-renderer": "^16.4.0" }, - "dependencies": { - "erlang-processes": "^2.0.0", - "erlang-types": "^1.0.1" + "peerDependencies": { + "react": "^16.4.0" } } diff --git a/src/index.js b/src/index.js index d0810ee..dd6763c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,24 +1,55 @@ -// export { self } from './pid' -export { start, self, spawn, send, receive, isAlive } from "./process"; +import React from "react"; -export {PID } from "erlang-types" -// export class GenServer { -// constructor(initialProps) { -// this.getInitialState && this.setState(this.getInitialState(initialProps)); -// } +import { isImmutable } from "./isImmutable"; -// setState(updater) { -// let nextState = updater; -// if (typeof updater == "function") { -// nextState = updater(this.state); -// } +export class ReComponent extends React.Component { + constructor(props) { + super(props); -// this.state = Object.assign({}, this.state, nextState); -// } + if (__DEV__) { + if(typeof this.reducer !== 'function') { + const name = this.constructor.name || this.displayName + throw new Error(name + '(...): No `reducer` method found on the returned component ' + + 'instance: did you define a reducer?') + } + } -// cast() {} + let stateIsImmutable = false; + if (this.initialState) { + let initialState = this.initialState(props); -// call() {} -// } + if (isImmutable(initialState)) { + stateIsImmutable = true; + initialState = { immutableState: initialState }; -// export { start, spawn, send, receive }; + // Define Immutable.js helpers + this.setImmutableState = updater => { + this.setState({ immutableState: updater(this.immutableState) }); + }; + Object.defineProperty(this, "immutableState", { + get: () => this.state.immutableState + }); + } + + this.state = initialState; + } + + this.send = action => { + const reduce = state => this.reducer(action, state) + + if (stateIsImmutable) { + this.setImmutableState(reduce); + } else { + this.setState(reduce); + } + }; + + this.createDispatcher = type => { + return payload => + this.send({ + type, + payload + }); + }; + } +} diff --git a/src/invariant.js b/src/invariant.js deleted file mode 100644 index f6e3959..0000000 --- a/src/invariant.js +++ /dev/null @@ -1,5 +0,0 @@ -export function invariant(condition, message) { - if (!condition) { - throw new Error(`Assertion failed: ${message || 'Condition not met'}`) - } -} diff --git a/src/isImmutable.js b/src/isImmutable.js new file mode 100644 index 0000000..1da646f --- /dev/null +++ b/src/isImmutable.js @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @see https://github.com/facebook/immutable-js/blob/v4.0.0-rc.9/src/Predicates.js + */ + +export function isImmutable(maybeImmutable) { + return isCollection(maybeImmutable) || isRecord(maybeImmutable); +} + +function isCollection(maybeCollection) { + return !!(maybeCollection && maybeCollection[IS_ITERABLE_SENTINEL]); +} + +function isRecord(maybeRecord) { + return !!(maybeRecord && maybeRecord[IS_RECORD_SENTINEL]); +} + +export const IS_ITERABLE_SENTINEL = "@@__IMMUTABLE_ITERABLE__@@"; +export const IS_RECORD_SENTINEL = "@@__IMMUTABLE_RECORD__@@"; diff --git a/src/message-queue.js b/src/message-queue.js deleted file mode 100644 index d670a89..0000000 --- a/src/message-queue.js +++ /dev/null @@ -1,28 +0,0 @@ -// import { invariant } from "./invariant"; - -// export function createMessageQueue() { -// let queues = {}; - -// return { -// send: function send(action) { -// const { type } = action; -// invariant(type) - -// if (queues[type]) { -// queues[type].push(action) -// } else { -// queues[type] = [action] -// } -// }, - -// receive: async function receive(type) { -// const queue = queues[type] - -// if (queue && queue.length >= 1) { -// return queue.shift(); -// } else { -// throw new Error('soonish'); -// } -// } -// }; -// } diff --git a/src/pid.js b/src/pid.js deleted file mode 100644 index 4c9ccc1..0000000 --- a/src/pid.js +++ /dev/null @@ -1,22 +0,0 @@ -// export function Pid(pid) { -// this.pid = pid -// }; - -// let _uniqueProcessId = 0; -// export function createPid() { -// return new Pid(_uniqueProcessId++); -// } - -// export const mainThreadPid = createPid(); - -// let currentPid = mainThreadPid; -// export function withPid(fn, pid) { -// currentPid = pid; -// fn(); -// currentPid = mainThreadPid; -// } - - -// export function self() { -// return currentPid; -// } diff --git a/src/process.js b/src/process.js deleted file mode 100644 index 9c59bd5..0000000 --- a/src/process.js +++ /dev/null @@ -1,47 +0,0 @@ -import {ProcessSystem} from "erlang-processes"; - -const processSystem = new ProcessSystem(); - -// import { createPid, mainThreadPid, self } from "./pid"; -// import { createMessageQueue } from "./message-queue"; -import { invariant } from "./invariant"; - -// const processes = new Map(); -// processes.set(mainThreadPid, createMessageQueue()); - -// export function start(GenServer, initialProps = {}) { -// const server = new GenServer(initialProps); -// const pid = createPid(); - -// processes.set(pid, server); -// return pid; -// } - -export function self() { - return processSystem.pid(); -} - -export function spawn(process) { - return processSystem.spawn(process); -} - -export function send(pid, action) { - invariant(pid); - invariant(action); - - - return processSystem.send(pid, action); -} - -export async function receive(type = null) { - return new Promise(function*(resolve) { - yield processSystem.receive((a) => { - console.log('receive', a) - resolve(a) - }, 0, reject); - }) -} - -export function isAlive(pid) { - return processSystem.is_alive(pid); -} diff --git a/yarn.lock b/yarn.lock index a2c4e1b..df16333 100644 --- a/yarn.lock +++ b/yarn.lock @@ -141,6 +141,10 @@ arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -240,6 +244,14 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + babel-helper-call-delegate@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" @@ -373,6 +385,14 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + babel-plugin-syntax-object-rest-spread@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -565,6 +585,41 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" @@ -613,6 +668,12 @@ babel-preset-env@^1.7.0: invariant "^2.2.2" semver "^5.3.0" +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + babel-preset-jest@^23.0.1: version "23.0.1" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.0.1.tgz#631cc545c6cf021943013bcaf22f45d87fe62198" @@ -620,6 +681,17 @@ babel-preset-jest@^23.0.1: babel-plugin-jest-hoist "^23.0.1" babel-plugin-syntax-object-rest-spread "^6.13.0" +babel-preset-react@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" @@ -912,6 +984,10 @@ copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + core-js@^2.4.0, core-js@^2.5.0: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -1054,15 +1130,11 @@ electron-to-chromium@^1.3.47: version "1.3.48" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz#d3b0d8593814044e092ece2108fc3ac9aea4b900" -erlang-processes@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/erlang-processes/-/erlang-processes-2.0.0.tgz#e282fa46d1872245583dce2f1a082472006dfce3" +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" dependencies: - erlang-types "^1.0.0" - -erlang-types@^1.0.0, erlang-types@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.1.tgz#943a57a9324e0d0edc0273690a8c702686d9b780" + iconv-lite "~0.4.13" error-ex@^1.2.0: version "1.3.1" @@ -1238,6 +1310,18 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" +fbjs@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -1502,7 +1586,7 @@ iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" -iconv-lite@^0.4.4: +iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" dependencies: @@ -1710,7 +1794,7 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -1748,6 +1832,13 @@ isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -2251,7 +2342,7 @@ longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: @@ -2431,6 +2522,13 @@ needle@^2.2.0: iconv-lite "^0.4.4" sax "^1.2.4" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -2519,7 +2617,7 @@ oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -object-assign@^4.1.0: +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2740,6 +2838,20 @@ process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.6.0: + version "15.6.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -2773,6 +2885,37 @@ rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-dom@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.0.tgz#099f067dd5827ce36a29eaf9a6cdc7cbf6216b1e" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + +react-is@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.0.tgz#cc9fdc855ac34d2e7d9d2eb7059bbc240d35ffcf" + +react-test-renderer@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.4.0.tgz#0dbe0e24263e94e1830c7afb1f403707fad313a3" + dependencies: + fbjs "^0.8.16" + object-assign "^4.1.1" + prop-types "^15.6.0" + react-is "^16.4.0" + +react@^16.4.0: + version "16.4.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.0" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -3015,6 +3158,10 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -3332,6 +3479,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +ua-parser-js@^0.7.9: + version "0.7.18" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed" + uglify-js@^2.6: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -3430,6 +3581,10 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.19" +whatwg-fetch@>=0.10.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4"