├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── Api.md └── images │ ├── elm_arch.png │ ├── gus.png │ ├── vuelm_debug.png │ ├── vuelm_info.png │ └── vuelm_log.png ├── examples ├── counter │ ├── index.html │ └── stores │ │ └── counter.js ├── financial │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── src │ │ ├── components │ │ │ ├── actions │ │ │ │ └── index.vue │ │ │ ├── app.vue │ │ │ ├── bills │ │ │ │ ├── bill-form.vue │ │ │ │ ├── bill-list-item.vue │ │ │ │ ├── bill-list.vue │ │ │ │ └── index.vue │ │ │ ├── filters │ │ │ │ └── index.vue │ │ │ └── topnav.vue │ │ ├── index.css │ │ ├── index.js │ │ ├── models │ │ │ ├── bill.js │ │ │ └── bills.js │ │ ├── sass │ │ │ └── build.sass │ │ └── utils │ │ │ └── index.js │ └── webpack.config.js ├── gus │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── package.json │ ├── src │ │ ├── Guex.vue │ │ ├── components │ │ │ ├── Search.vue │ │ │ ├── UserList.vue │ │ │ └── UserRow.vue │ │ ├── index.js │ │ └── store │ │ │ └── user.js │ └── webpack.config.js └── taskmanager │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── src │ ├── TaskManager.vue │ ├── components │ │ ├── TaskFilter.vue │ │ ├── TaskForm.vue │ │ ├── TaskItem.vue │ │ ├── TaskList.vue │ │ └── Title.vue │ ├── index.js │ └── store │ │ └── task.js │ ├── webpack.config.js │ └── yarn.lock ├── index.js ├── package.json ├── src ├── connect.js ├── index.js ├── store.js └── util.js ├── test └── store_test.js ├── vuelm.config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["es2015", { "modules": false }] 4 | ], 5 | "plugins": [ 6 | "external-helpers" 7 | ] 8 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | package-lock.json 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Keuller Magalhaes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VuElm 2 | 3 | ### It's a Vue state management inspired by Elm architecture. 4 | 5 | ## Concepts 6 | 7 | There are basically four elements on Elm architecture: Model, Actions, Updates and View. 8 | 9 | ![alt text](https://github.com/keuller/vuelm/raw/master/docs/images/elm_arch.png) 10 | 11 | The image above describes the flow of Elm's architecture. **Vuelm** tries to bring it to Vue components. 12 | 13 | To know more about Elm Architecture, see this [link](http://guide.elm-lang.org/architecture/). 14 | 15 | ## Getting Started 16 | 17 | Let's to get started with a simple application: the counter. 18 | 19 | First lets create our model. The model is composed by 3 parts: state, updates and actions. 20 | 21 | ```javascript 22 | import { store, types } from 'vuelm' 23 | 24 | const Type = types('INCREMENT', 'DECREMENT') 25 | 26 | const state = { 27 | count: 0 28 | } 29 | 30 | const updates = { 31 | [Type.INCREMENT](state) { 32 | state.count = state.count + 1 33 | return state 34 | }, 35 | 36 | [Type.DECREMENT](state) { 37 | state.count = state.count - 1 38 | return state 39 | } 40 | } 41 | 42 | const actions = { 43 | increment() { 44 | this.update(Type.INCREMENT) 45 | }, 46 | 47 | decrement() { 48 | this.update(Type.DECREMENT) 49 | } 50 | } 51 | 52 | export default store(state, updates, actions) 53 | ``` 54 | 55 | The code above is pretty simple and straightforward. Ths state is representated by ```{ count: 0 }```. 56 | 57 | The updates may be of two types: ```INCREMENT``` or ```DECREMENT```. The updates is responsible for change the state and produces a new state after those changes. In this case we're just increment the **count** plus 1 or decrement minus 1. 58 | 59 | The actions just call ```this.update(type)``` method passing the **type** of update that we need to. 60 | 61 | To build the model object, we must to join those three elements, passing to ```store``` function as arguments. 62 | 63 | Now we need to create our Vue component that will render the **counter**. The code below show the counter component: 64 | 65 | ```html 66 | 75 | 76 | 89 | 90 | ``` 91 | 92 | This component has two buttons which are used to invoke actions from our store. We use ```connect``` function to bind the component with store. You can call actions directly from store, as you can see in above example, we associate ```increment``` and ```decrement``` action into component. 93 | 94 | As we can see Vuelm brings the simplicity and powerful design from Elm architecture to our Vue components. 95 | 96 | ## How To Install 97 | 98 | To install Vuelm, you can use: 99 | 100 | ```bash 101 | $ yarn add vuelm // npm install vuelm -S 102 | ``` 103 | 104 | Or you can use [vue-starter](https://github.com/keuller/vue-starter) template, as shown below: 105 | 106 | ```javascript 107 | $ vue init keuller/vue-starter [project-name] 108 | ``` 109 | 110 | See the examples to learn more about Vuelm. 111 | 112 | ## See Online Demos 113 | 114 | * [Counter Demo](http://keuller.com/vuelm/demos/counter/) 115 | * [Task Manager Demo](http://keuller.com/vuelm/demos/taskman/) 116 | * [GUS Demo](http://keuller.com/vuelm/demos/gus/) 117 | * [Financial](http://keuller.com/vuelm/demos/financial) 118 | 119 | -------------------------------------------------------------------------------- /docs/Api.md: -------------------------------------------------------------------------------- 1 | # Vuelm API 2 | 3 | This document describes the VuElm API. 4 | 5 | ### Vuelm.store(state, updates, stores) 6 | 7 | This method create your store object that represents the state of application. 8 | 9 | ```javascript 10 | import { store } from 'vuelm' 11 | 12 | const state = { ... } 13 | 14 | const updates = { ... } 15 | 16 | const actions = { ... } 17 | 18 | export default store(state, updates, actions) 19 | ``` 20 | 21 | To enable logging to specific store, just change the **logger** property to true. 22 | 23 | ```javascript 24 | const mystore = store(state, updates, actions) 25 | mystore.logger = true 26 | 27 | export default mystore 28 | ``` 29 | 30 | ### Vuelm.connect(component, models) 31 | 32 | This function binds the Vue component with one or more models. 33 | 34 | ```javascript 35 | import { connect } from 'vuelm' 36 | import counter from 'models/counter' 37 | 38 | const Counter = { 39 | // component code goes here 40 | } 41 | 42 | export default connect(Counter, { counter }) 43 | ``` 44 | 45 | The first argument is the Vue component and the second one, must be a literal object with all stores you wish to bind with. When you has more than one model bound to component, Vuelm merge all states of each model into a single one. 46 | 47 | ### Vuelm.types(...args) 48 | 49 | This function create a literal object that will be used as update type. You must pass a list of strings constants. 50 | 51 | ```javascript 52 | import { types } from 'vuelm' 53 | 54 | const Types = types('INCREMENT', 'DECREMENT') 55 | 56 | // you can use it as constant types 57 | const actions = { 58 | increment() { 59 | this.update(Types.INCREMENT) 60 | } 61 | } 62 | ``` 63 | 64 | ### update(type, data) 65 | 66 | This method is used to send an update to model, specifying the update type and some data (optional). 67 | 68 | ```javascript 69 | const actions = { 70 | addTask(task) { 71 | this.update(Types.ADD_TASK, task) 72 | } 73 | } 74 | ``` 75 | 76 | ### sync(data) 77 | 78 | This method synchronizes ViewModel data to model. This method is added automatically into Vue component instance. You can see the use of this feature in *Financial* example. 79 | 80 | ```javascript 81 | this.sync(this.$data) 82 | ``` 83 | -------------------------------------------------------------------------------- /docs/images/elm_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keuller/vuelm/f2a501a7919e9e4cae0c260952c8526e19632b9d/docs/images/elm_arch.png -------------------------------------------------------------------------------- /docs/images/gus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keuller/vuelm/f2a501a7919e9e4cae0c260952c8526e19632b9d/docs/images/gus.png -------------------------------------------------------------------------------- /docs/images/vuelm_debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keuller/vuelm/f2a501a7919e9e4cae0c260952c8526e19632b9d/docs/images/vuelm_debug.png -------------------------------------------------------------------------------- /docs/images/vuelm_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keuller/vuelm/f2a501a7919e9e4cae0c260952c8526e19632b9d/docs/images/vuelm_info.png -------------------------------------------------------------------------------- /docs/images/vuelm_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/keuller/vuelm/f2a501a7919e9e4cae0c260952c8526e19632b9d/docs/images/vuelm_log.png -------------------------------------------------------------------------------- /examples/counter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vuelm Counter 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 |

Vuelm Counter Example

20 | 21 | {{count}} 22 |
23 | 24 | 25 |
26 |
27 | 28 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /examples/counter/stores/counter.js: -------------------------------------------------------------------------------- 1 | var Type = Vuelm.types('INCREMENT', 'DECREMENT') 2 | 3 | var state = { 4 | count: 0 5 | } 6 | 7 | var updates = { 8 | [Type.INCREMENT]: function(state) { 9 | state.count = state.count + 1 10 | return state 11 | }, 12 | 13 | [Type.DECREMENT]: function(state) { 14 | state.count = state.count - 1 15 | return state 16 | } 17 | } 18 | 19 | var actions = { 20 | increment: function() { 21 | this.update(Type.INCREMENT) 22 | }, 23 | decrement: function() { 24 | this.update(Type.DECREMENT) 25 | } 26 | } 27 | 28 | var Counter = Vuelm.store(state, updates, actions) 29 | -------------------------------------------------------------------------------- /examples/financial/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/* 3 | dist/* 4 | yarn.lock -------------------------------------------------------------------------------- /examples/financial/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Financial 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/financial/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "financial", 3 | "version": "1.0.0", 4 | "description": "Task Manager Vuelm example", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --inline --hot", 8 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 9 | }, 10 | "keywords": [ 11 | "vue", 12 | "vuelm", 13 | "state management", 14 | "example" 15 | ], 16 | "author": "Keuller Magalhaes", 17 | "license": "MIT", 18 | "babel": { 19 | "presets": [ 20 | "es2015", 21 | "stage-2", 22 | [ 23 | "env", 24 | { 25 | "targets": { 26 | "browsers": [ 27 | "last 2 versions", 28 | "chrome >= 59", 29 | "firefox >= 55" 30 | ] 31 | } 32 | } 33 | ] 34 | ] 35 | }, 36 | "dependencies": { 37 | "bulma": "^0.6.0", 38 | "vue": "^2.4.4", 39 | "vuelm": "^0.8.3" 40 | }, 41 | "devDependencies": { 42 | "babel-core": "^6.26.0", 43 | "babel-loader": "^7.1.2", 44 | "babel-preset-env": "^1.6.0", 45 | "babel-preset-es2015": "^6.24.1", 46 | "babel-preset-stage-2": "^6.24.1", 47 | "clean-webpack-plugin": "^0.1.17", 48 | "cross-env": "^5.0.5", 49 | "css-loader": "^0.28.5", 50 | "extract-text-webpack-plugin": "^3.0.1", 51 | "file-loader": "^1.1.5", 52 | "json-loader": "^0.5.4", 53 | "node-sass": "^4.5.3", 54 | "sass-loader": "^6.0.6", 55 | "url-loader": "^0.6.2", 56 | "vue-hot-reload-api": "^2.1.1", 57 | "vue-loader": "^13.0.5", 58 | "vue-style-loader": "^3.0.2", 59 | "vue-template-compiler": "^2.4.4", 60 | "webpack": "^3.4.1", 61 | "webpack-dev-server": "^2.6.1" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/financial/src/components/actions/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | -------------------------------------------------------------------------------- /examples/financial/src/components/app.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 43 | -------------------------------------------------------------------------------- /examples/financial/src/components/bills/bill-form.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 96 | -------------------------------------------------------------------------------- /examples/financial/src/components/bills/bill-list-item.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 38 | 39 | 42 | 43 | -------------------------------------------------------------------------------- /examples/financial/src/components/bills/bill-list.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 37 | -------------------------------------------------------------------------------- /examples/financial/src/components/bills/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 44 | -------------------------------------------------------------------------------- /examples/financial/src/components/filters/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 49 | -------------------------------------------------------------------------------- /examples/financial/src/components/topnav.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /examples/financial/src/index.css: -------------------------------------------------------------------------------- 1 | html, body { background-color: #efefef } 2 | #topbar > .navbar-brand > .navbar-item, 3 | #topbar > .navbar-menu > .navbar-start > .navbar-item, 4 | #topbar > .navbar-menu > .navbar-end > .navbar-item { color:#EFEFEF !important; } 5 | -------------------------------------------------------------------------------- /examples/financial/src/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import 'sass/build.sass' 3 | import 'index.css' 4 | import App from 'components/app' 5 | 6 | document.addEventListener('DOMContentLoaded', (ev) => { 7 | let app = new Vue({ 8 | render: h => h(App) 9 | }) 10 | app.$mount('#app') 11 | }) 12 | -------------------------------------------------------------------------------- /examples/financial/src/models/bill.js: -------------------------------------------------------------------------------- 1 | import { store, types } from 'vuelm' 2 | 3 | const Type = types('CLEAN', 'SET', 'VALIDATE') 4 | 5 | const state = { 6 | errors: {}, 7 | id: '', 8 | title: '', 9 | dueDate: '', 10 | paid: false, 11 | value: 0 12 | } 13 | 14 | const updates = { 15 | [Type.CLEAN](state) { 16 | return { id:'', title:'', dueDate:'', paid: false, value: 0, errors: {} } 17 | }, 18 | 19 | [Type.VALIDATE](state) { 20 | let errors = {} 21 | 22 | if (state.title == '') errors['title'] = 'Fill title field.' 23 | if (state.dueDate == '') errors['dueDate'] = 'Fill Due Date field.' 24 | 25 | let val = parseFloat(state.value) 26 | if (isNaN(val)) errors['value'] = 'Value field is invalid number.' 27 | if (val <= 0) 28 | errors['value'] = 'Value must be greater than 0.' 29 | else 30 | state.value = val 31 | 32 | return {...state, errors } 33 | } 34 | } 35 | 36 | const actions = { 37 | clean() { 38 | this.update(Type.CLEAN) 39 | }, 40 | 41 | validate() { 42 | this.update(Type.VALIDATE) 43 | } 44 | } 45 | 46 | export default store(state, updates, actions) 47 | -------------------------------------------------------------------------------- /examples/financial/src/models/bills.js: -------------------------------------------------------------------------------- 1 | import { store, types } from 'vuelm' 2 | import { convertDate } from 'utils' 3 | 4 | const Type = types('ADD', 'REMOVE', 'UPDATE', 'APPLY_FILTER') 5 | 6 | const sortByDate = (b1, b2) => { 7 | let dt1 = new Date(b1.dueDate), dt2 = new Date(b2.dueDate) 8 | return ((dt1 > dt2) ? 1 : (dt1 < dt2) ? -1 : 0) 9 | } 10 | 11 | const sum = (list) => list.reduce((prev, bill) => prev + bill.value, 0) 12 | const filterByPaid = (list) => list.filter(bill => bill.paid == true) 13 | const filterByUnpaid = (list) => list.filter(bill => bill.paid == false) 14 | const filterByOverdue = (list) => list.filter(bill => { 15 | let dueDate = new Date(bill.dueDate), today = new Date() 16 | return (bill.paid == false && dueDate < today) 17 | }) 18 | 19 | const FIXTURE = [ 20 | { id:'agbd43', title: 'Netflix', dueDate: '2017-09-05 00:00:00', value: 15.99, paid: true }, 21 | { id:'fve491', title: 'Internet', dueDate: '2017-09-10 00:00:00', value: 59.99, paid: false }, 22 | { id:'6tg2x0', title: 'Gas', dueDate: '2017-09-15 00:00:00', value: 15.5, paid: false } 23 | ] 24 | 25 | const state = { 26 | raw: FIXTURE, 27 | bills: FIXTURE, 28 | filter: 'ALL', 29 | balance: sum(FIXTURE) 30 | } 31 | 32 | const updates = { 33 | [Type.APPLY_FILTER](state, value) { 34 | switch(value) { 35 | case 'PAID': { 36 | state.bills = filterByPaid(state.raw) 37 | break 38 | } 39 | case 'UNPAID': { 40 | state.bills = filterByUnpaid(state.raw) 41 | break 42 | } 43 | case 'OVERDUE': { 44 | state.bills = filterByOverdue(state.raw) 45 | break 46 | } 47 | default: state.bills = [...state.raw] 48 | } 49 | 50 | state.filter = value 51 | state.balance = sum(state.bills) 52 | state.bills.sort(sortByDate) 53 | 54 | return {...state} 55 | }, 56 | 57 | [Type.ADD](state, bill) { 58 | bill.id = 'xyz' + Math.round(Math.random() * 2 + 1) 59 | bill.dueDate = convertDate(bill.dueDate) 60 | bill.paid = false 61 | state.raw.push(bill) 62 | 63 | return {...state} 64 | }, 65 | 66 | [Type.UPDATE](state, bill) { 67 | let nBills = state.raw.filter(item => item.id !== bill.id) 68 | bill.dueDate = convertDate(bill.dueDate) 69 | nBills.push(bill) 70 | 71 | return {...state, raw: nBills} 72 | }, 73 | 74 | [Type.REMOVE](state, id) { 75 | let nBills = state.raw.filter(bill => bill.id != id) 76 | return {...state, raw: nBills} 77 | } 78 | 79 | } 80 | 81 | const actions = { 82 | applyFilter(value) { 83 | this.update(Type.APPLY_FILTER, value) 84 | }, 85 | 86 | addBill(bill) { 87 | const { filter } = this.state() 88 | this.update(Type.ADD, bill) 89 | this.applyFilter(filter) 90 | }, 91 | 92 | updateBill(bill) { 93 | const { filter } = this.state() 94 | this.update(Type.UPDATE, bill) 95 | this.applyFilter(filter) 96 | }, 97 | 98 | removeBill(id) { 99 | const { filter } = this.state() 100 | this.update(Type.REMOVE, id) 101 | this.applyFilter(filter) 102 | } 103 | } 104 | 105 | export default store(state, updates, actions) 106 | -------------------------------------------------------------------------------- /examples/financial/src/sass/build.sass: -------------------------------------------------------------------------------- 1 | @charset "utf-8" 2 | 3 | @import "~bulma/sass/utilities/initial-variables.sass" 4 | @import "~bulma/sass/utilities/functions.sass" 5 | 6 | $primary: #3b5999 7 | $navbar-background-color: $primary 8 | $navbar-item-color: #ffffff 9 | 10 | @import "~bulma/sass/utilities/derived-variables.sass" 11 | @import "~bulma/sass/utilities/animations.sass" 12 | @import "~bulma/sass/utilities/mixins.sass" 13 | @import "~bulma/sass/utilities/controls.sass" 14 | 15 | @import '~bulma/sass/base/_all.sass' 16 | @import '~bulma/sass/grid/_all.sass' 17 | 18 | // '~bulma/sass/layout/_all.sass' 19 | @import '~bulma/sass/layout/hero.sass' 20 | 21 | // '~bulma/sass/elements/_all.sass' 22 | @import "~bulma/sass/elements/box.sass" 23 | @import "~bulma/sass/elements/button.sass" 24 | @import "~bulma/sass/elements/image.sass" 25 | @import "~bulma/sass/elements/container.sass" 26 | @import "~bulma/sass/elements/tag.sass" 27 | @import "~bulma/sass/elements/title.sass" 28 | 29 | // '~bulma/sass/components/_all.sass' 30 | @import '~bulma/sass/components/card.sass' 31 | @import '~bulma/sass/components/level.sass' 32 | @import '~bulma/sass/components/media.sass' 33 | @import '~bulma/sass/components/navbar.sass' 34 | 35 | // @import 'pageloader.sass' -------------------------------------------------------------------------------- /examples/financial/src/utils/index.js: -------------------------------------------------------------------------------- 1 | 2 | export function formatDate(value) { 3 | let dt = new Date(value) 4 | let year = dt.getFullYear(), month = dt.getMonth() + 1, day = dt.getDate() 5 | if (month < 10) month = `0${month}` 6 | if (day < 10) day = `0${day}` 7 | return `${day}/${month}/${year}` 8 | } 9 | 10 | export function convertDate(value) { 11 | let values = value.split('/') 12 | return `${values[2]}-${values[1]}-${values[0]} 00:00:00` 13 | } 14 | 15 | export function formatMoney(value) { 16 | let val = new Number(value) 17 | return `\$ ${val.toFixed(2)}` 18 | } 19 | -------------------------------------------------------------------------------- /examples/financial/webpack.config.js: -------------------------------------------------------------------------------- 1 | let path = require('path') 2 | let webpack = require('webpack') 3 | , ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | , CleanWebpackPlugin = require('clean-webpack-plugin') 5 | 6 | let extractCSS = new ExtractTextPlugin("css/app.css") 7 | , extractSCSS = new ExtractTextPlugin("css/build.css") 8 | 9 | let config = { 10 | entry:{ 11 | bundle: path.join(__dirname, 'src/index.js'), 12 | runtime: ['vue'] 13 | }, 14 | 15 | output: { 16 | path: path.join(__dirname, 'dist'), 17 | publicPath: '/dist/', 18 | filename: '[name].js' 19 | }, 20 | 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.(js)$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/ 27 | }, { 28 | test: /\.vue$/, 29 | loader: 'vue-loader' 30 | }, { 31 | test: /\.css$/, 32 | use: extractCSS.extract([ 'css-loader' ]) 33 | }, { 34 | test: /\.sass$/, 35 | use: extractSCSS.extract([ 'css-loader', 'sass-loader' ]) 36 | }, { 37 | test: /\.(png|jpg|gif|svg)$/, 38 | loader: 'file-loader', 39 | options: { 40 | name: '[name].[ext]?[hash]' 41 | } 42 | } 43 | ] 44 | }, 45 | 46 | resolve: { 47 | modules: ['src', 'node_modules'], 48 | extensions: ['.js', '.vue'] 49 | }, 50 | 51 | devServer: { 52 | historyApiFallback: true, 53 | port: '8080', 54 | noInfo: true 55 | }, 56 | 57 | devtool: '#eval-source-map', 58 | 59 | plugins: [ 60 | new webpack.NoEmitOnErrorsPlugin(), 61 | new CleanWebpackPlugin(['dist']), 62 | extractSCSS, 63 | extractCSS, 64 | new webpack.optimize.CommonsChunkPlugin({ 65 | name: ['runtime'], 66 | warnings: false 67 | }) 68 | ] 69 | } 70 | 71 | if (process.env.NODE_ENV === 'production') { 72 | config.devtool = '#source-map' 73 | config.plugins = (config.plugins || []).concat([ 74 | new webpack.DefinePlugin({ 75 | 'process.env': { 76 | NODE_ENV: '"production"' 77 | } 78 | }), 79 | new webpack.optimize.UglifyJsPlugin({ 80 | compress: { 81 | warnings: false 82 | } 83 | }), 84 | new webpack.LoaderOptionsPlugin({ 85 | minimize: true 86 | }) 87 | ]) 88 | } 89 | 90 | module.exports = config 91 | -------------------------------------------------------------------------------- /examples/gus/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/* 3 | dist/* 4 | yarn.lock -------------------------------------------------------------------------------- /examples/gus/README.md: -------------------------------------------------------------------------------- 1 | # Github User Search Example 2 | 3 | This example show how to use external API with Vuelm. 4 | 5 | ![alt text](https://github.com/keuller/vuelm/raw/master/docs/images/gus.png) 6 | -------------------------------------------------------------------------------- /examples/gus/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GUEx 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/gus/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gus", 3 | "version": "1.2.0", 4 | "description": "Github User Search example", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --inline --hot", 8 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 9 | }, 10 | "keywords": [ 11 | "vue", 12 | "vuelm", 13 | "state management" 14 | ], 15 | "author": "Keuller Magalhaes", 16 | "license": "MIT", 17 | "babel": { 18 | "presets": [ 19 | "es2015", 20 | "stage-2", 21 | [ "env", 22 | { 23 | "targets": { 24 | "browsers": [ 25 | "last 2 versions", 26 | "chrome >= 58", 27 | "firefox >= 54" 28 | ] 29 | } 30 | } 31 | ] 32 | ] 33 | }, 34 | "dependencies": { 35 | "axios": "^0.16.2", 36 | "vue": "^2.4.4", 37 | "vuelm": "^0.8.3" 38 | }, 39 | "devDependencies": { 40 | "babel-core": "^6.26.0", 41 | "babel-loader": "^7.1.2", 42 | "babel-preset-env": "^1.6.0", 43 | "babel-preset-es2015": "^6.24.1", 44 | "babel-preset-stage-2": "^6.24.1", 45 | "cross-env": "^5.0.5", 46 | "css-loader": "^0.28.7", 47 | "file-loader": "^1.1.5", 48 | "json-loader": "^0.5.4", 49 | "url-loader": "^0.6.2", 50 | "vue-loader": "^13.0.5", 51 | "vue-style-loader": "^3.0.3", 52 | "vue-template-compiler": "^2.4.4", 53 | "webpack": "^2.2.1", 54 | "webpack-dev-server": "^2.4.2" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /examples/gus/src/Guex.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 35 | -------------------------------------------------------------------------------- /examples/gus/src/components/Search.vue: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /examples/gus/src/components/UserList.vue: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 43 | -------------------------------------------------------------------------------- /examples/gus/src/components/UserRow.vue: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | -------------------------------------------------------------------------------- /examples/gus/src/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Guex from 'Guex' 3 | 4 | const app = new Vue({ 5 | render: (h) => h(Guex) 6 | }) 7 | 8 | app.$mount('#app') 9 | -------------------------------------------------------------------------------- /examples/gus/src/store/user.js: -------------------------------------------------------------------------------- 1 | import { store, types } from 'vuelm' 2 | import axios from 'axios' 3 | 4 | const Type = types('GET_USERS', 'CLEAR_USERS') 5 | const baseUrl = 'https://api.github.com' 6 | 7 | const state = { 8 | users: [] 9 | } 10 | 11 | const updates = { 12 | [Type.CLEAR_USERS](state) { 13 | state.users = [] 14 | return {...state} 15 | }, 16 | 17 | [Type.GET_USERS](state, list) { 18 | state.users = [...list] 19 | return state 20 | } 21 | } 22 | 23 | const actions = { 24 | clear() { 25 | this.update(Type.CLEAR_USERS) 26 | }, 27 | 28 | search(obj) { 29 | let params = `?q=${obj.text}` 30 | axios.get(`${baseUrl}/search/users${params}`).then(result => { 31 | this.update(Type.GET_USERS, result.data.items) 32 | }).catch(err => { 33 | console.error(err) 34 | }) 35 | } 36 | } 37 | 38 | export default store(state, updates, actions) 39 | -------------------------------------------------------------------------------- /examples/gus/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | , webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: { 6 | bundle: './src/index.js', 7 | vendor: ['vue', 'vuelm'] 8 | }, 9 | 10 | output: { 11 | path: path.resolve(__dirname, './dist'), 12 | publicPath: '/dist/', 13 | filename: '[name].js' 14 | }, 15 | 16 | resolve: { 17 | extensions: ['.js', '.vue'], 18 | modules: ['src', 'node_modules'] 19 | }, 20 | 21 | node: { 22 | fs: 'empty' 23 | }, 24 | 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.css$/, 29 | loader: "style!css" 30 | }, 31 | { 32 | test: /\.vue$/, 33 | loader: 'vue-loader' 34 | }, 35 | { 36 | test: /\.js$/, 37 | loader: 'babel-loader', 38 | exclude: /node_modules/ 39 | }, 40 | { 41 | test: /\.json$/, 42 | loader: 'json-loader' 43 | }, 44 | { 45 | test: /\.(png|jpg|gif|svg)$/, 46 | loader: 'url-loader', 47 | query: { 48 | limit: 10000, 49 | name: '[name].[ext]?[hash]' 50 | } 51 | } 52 | ] 53 | }, 54 | 55 | devServer: { 56 | historyApiFallback: true, 57 | port: 8080, 58 | noInfo: true 59 | }, 60 | 61 | devtool: '#eval-source-map', 62 | 63 | plugins: [ 64 | new webpack.NoEmitOnErrorsPlugin(), 65 | new webpack.optimize.CommonsChunkPlugin({ 66 | name: ['vendor'], 67 | warnings: false 68 | }) 69 | ] 70 | } 71 | 72 | if (process.env.NODE_ENV === 'production') { 73 | module.exports.devtool = '#source-map' 74 | 75 | module.exports.plugins = (module.exports.plugins || []).concat([ 76 | new webpack.DefinePlugin({ 77 | 'process.env': { 78 | NODE_ENV: '"production"' 79 | } 80 | }), 81 | new webpack.optimize.UglifyJsPlugin({ 82 | comments: false, 83 | sourceMap: false, 84 | compress: { 85 | warnings: false, 86 | conditionals: true, 87 | warnings: false, 88 | dead_code: true, 89 | unused: true, 90 | evaluate: true, 91 | } 92 | }), 93 | new webpack.LoaderOptionsPlugin({ 94 | minimize: true 95 | }) 96 | ]) 97 | } 98 | -------------------------------------------------------------------------------- /examples/taskmanager/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/* 3 | dist/* 4 | yarn.lock 5 | -------------------------------------------------------------------------------- /examples/taskmanager/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Task Manager 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /examples/taskmanager/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "taskmanager", 3 | "version": "1.2.0", 4 | "description": "Task Manager Vuelm example", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --inline --hot", 8 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules" 9 | }, 10 | "keywords": [ 11 | "vue", 12 | "vuelm", 13 | "state management" 14 | ], 15 | "author": "Keuller Magalhaes", 16 | "license": "MIT", 17 | "babel": { 18 | "presets": [ 19 | [ 20 | "es2015", 21 | "stage-2" 22 | ] 23 | ] 24 | }, 25 | "dependencies": { 26 | "vue": "^2.4.4", 27 | "vuelm": "^0.8.3" 28 | }, 29 | "devDependencies": { 30 | "babel-core": "^6.26.0", 31 | "babel-loader": "^7.1.2", 32 | "babel-preset-es2015": "^6.24.1", 33 | "babel-preset-stage-2": "^6.24.1", 34 | "cross-env": "^5.0.5", 35 | "css-loader": "^0.28.7", 36 | "file-loader": "^1.1.5", 37 | "json-loader": "^0.5.7", 38 | "url-loader": "^0.5.7", 39 | "vue-hot-reload-api": "^2.1.1", 40 | "vue-loader": "^13.0.5", 41 | "vue-style-loader": "^3.0.3", 42 | "vue-template-compiler": "^2.4.4", 43 | "webpack": "^3.4.1", 44 | "webpack-dev-server": "^2.6.1" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/taskmanager/src/TaskManager.vue: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 48 | -------------------------------------------------------------------------------- /examples/taskmanager/src/components/TaskFilter.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 28 | 29 | 70 | -------------------------------------------------------------------------------- /examples/taskmanager/src/components/TaskForm.vue: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 29 | -------------------------------------------------------------------------------- /examples/taskmanager/src/components/TaskItem.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 33 | -------------------------------------------------------------------------------- /examples/taskmanager/src/components/TaskList.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 28 | 29 | 52 | -------------------------------------------------------------------------------- /examples/taskmanager/src/components/Title.vue: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 17 | -------------------------------------------------------------------------------- /examples/taskmanager/src/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuelm from 'vuelm' 3 | import TaskManager from 'TaskManager' 4 | 5 | const app = new Vue({ 6 | render: (h) => h(TaskManager) 7 | }) 8 | 9 | app.$mount('#app') 10 | -------------------------------------------------------------------------------- /examples/taskmanager/src/store/task.js: -------------------------------------------------------------------------------- 1 | import { store, types } from 'vuelm' 2 | 3 | const Type = types( 4 | 'ADD_TASK', 'END_TASK', 'CLEAR_COMPLETED', 'FILTER_TASK' 5 | ) 6 | 7 | const state = { 8 | tasks: [], 9 | filter: 'ALL' 10 | } 11 | 12 | const updates = { 13 | [Type.ADD_TASK](state, data) { 14 | state.tasks = [...state.tasks, data] 15 | return state 16 | }, 17 | 18 | [Type.END_TASK](state, task) { 19 | let idx = state.tasks.findIndex(item => item.text === task.text) 20 | state.tasks[idx].completed = !state.tasks[idx].completed 21 | return state 22 | }, 23 | 24 | [Type.CLEAR_COMPLETED](state) { 25 | state.tasks = state.tasks.filter(task => !task.completed) 26 | state.filter = 'ALL' 27 | return state 28 | }, 29 | 30 | [Type.FILTER_TASK](state, filter) { 31 | state.filter = filter 32 | return state 33 | } 34 | } 35 | 36 | // actions that will update the state 37 | const actions = { 38 | addTask(task) { 39 | this.update(Type.ADD_TASK, task) 40 | }, 41 | 42 | completeTask(task) { 43 | this.update(Type.END_TASK, task) 44 | }, 45 | 46 | doFilter(type) { 47 | this.update(Type.FILTER_TASK, type) 48 | }, 49 | 50 | clearCompleted() { 51 | this.update(Type.CLEAR_COMPLETED) 52 | } 53 | } 54 | 55 | export default store(state, updates, actions) 56 | -------------------------------------------------------------------------------- /examples/taskmanager/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: { 6 | bundle: './src/index.js', 7 | vendor: ['vue', 'vuelm'] 8 | }, 9 | 10 | output: { 11 | path: path.resolve(__dirname, './dist'), 12 | publicPath: '/dist/', 13 | filename: '[name].js' 14 | }, 15 | 16 | resolve: { 17 | extensions: ['.js', '.vue'], 18 | modules: ['src', 'node_modules'] 19 | }, 20 | 21 | node: { 22 | fs: 'empty' 23 | }, 24 | 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.css$/, 29 | loader: "style!css" 30 | }, 31 | { 32 | test: /\.vue$/, 33 | loader: 'vue-loader' 34 | }, 35 | { 36 | test: /\.js$/, 37 | loader: 'babel-loader', 38 | exclude: /node_modules/ 39 | }, 40 | { 41 | test: /\.json$/, 42 | loader: 'json-loader' 43 | }, 44 | { 45 | test: /\.(png|jpg|gif|svg)$/, 46 | loader: 'url-loader', 47 | query: { 48 | limit: 10000, 49 | name: '[name].[ext]?[hash]' 50 | } 51 | } 52 | ] 53 | }, 54 | 55 | devServer: { 56 | historyApiFallback: true, 57 | noInfo: true 58 | }, 59 | 60 | devtool: '#eval-source-map', 61 | 62 | plugins: [ 63 | new webpack.NoEmitOnErrorsPlugin(), 64 | new webpack.optimize.CommonsChunkPlugin({ 65 | name: ['vendor'], 66 | warnings: false 67 | }) 68 | ] 69 | } 70 | 71 | if (process.env.NODE_ENV === 'production') { 72 | module.exports.devtool = '#source-map' 73 | 74 | module.exports.plugins = (module.exports.plugins || []).concat([ 75 | new webpack.DefinePlugin({ 76 | 'process.env': { 77 | NODE_ENV: '"production"' 78 | } 79 | }), 80 | new webpack.optimize.UglifyJsPlugin({ 81 | comments: false, 82 | sourceMap: false, 83 | compress: { 84 | warnings: false, 85 | conditionals: true, 86 | warnings: false, 87 | dead_code: true, 88 | unused: true, 89 | evaluate: true, 90 | } 91 | }), 92 | new webpack.LoaderOptionsPlugin({ 93 | minimize: true 94 | }) 95 | ]) 96 | } 97 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):t.Vuelm=n()}(this,function(){"use strict";function t(t,n){return n.split(".").reduce(function(t,n){return t[n]},t)}function n(t,e){for(var o in e)!function(o){var i=null;Array.isArray(e[o])?(i=[],e[o].forEach(function(t){i.push(n({},t))})):i="object"===r(e[o])?n({},e[o]):e[o],t[o]=i}(o);return t}function e(t,n){var e=t.methods||{},o=t.name||"unknown",i=["get","update","observe","_notify"];for(var s in n)"function"!=r(n[s])||function(t){return i.filter(function(n){return n==t}).length>0}(s)||(e.hasOwnProperty(s)?console.warn("Component '%s' already have a method called '%s'",o,s):e[s]=n[s].bind(n));e.sync=function(t){var n=JSON.parse(JSON.stringify(t));this.update("SYNC_MODEL",n)}.bind(n),t.methods=e}function o(t,e,o){if(e.SYNC_MODEL=function(t,e){return n(t,e)},this._subscriber_id=100,this._subscribers={},this.logger=!1,this._options={state:t,updates:e},void 0!==o||null!==o)for(var r in o)this[r]=o[r]}var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(){function t(t){this.value=t}function n(n){function e(r,i){try{var s=n[r](i),u=s.value;u instanceof t?Promise.resolve(u.value).then(function(t){e("next",t)},function(t){e("throw",t)}):o(s.done?"return":"normal",s.value)}catch(t){o("throw",t)}}function o(t,n){switch(t){case"return":r.resolve({value:n,done:!0});break;case"throw":r.reject(n);break;default:r.resolve({value:n,done:!1})}(r=r.next)?e(r.key,r.arg):i=null}var r,i;this._invoke=function(t,n){return new Promise(function(o,s){var u={key:t,arg:n,resolve:o,reject:s,next:null};i?i=i.next=u:(r=i=u,e(t,n))})},"function"!=typeof n.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(n.prototype[Symbol.asyncIterator]=function(){return this}),n.prototype.next=function(t){return this._invoke("next",t)},n.prototype.throw=function(t){return this._invoke("throw",t)},n.prototype.return=function(t){return this._invoke("return",t)}}();o.prototype={_notify:function(){var t=n({},this._options.state);for(var e in this._subscribers)this._subscribers[e](t);t=null},state:function(){return n({},this._options.state)},get:function(n){return t(this._options.state,n)},update:function(t,e){var o=n({},this._options.state),r={};this.logger&&console.group&&console.group(t),this.logger&&console.log("Old State:",o),"function"==typeof this._options.updates[t]?(r=this._options.updates[t].call(this,o,e),this._options.state=r):r=o,this.logger&&console.log("New State:",r),this.logger&&console.groupEnd&&console.groupEnd(),this._notify(),o=null,r=null},observe:function(t){var n=this,e=this._subscriber_id++;return n._subscribers[e]=function(e){t.call(n,e)},function(){var t=e;delete n._subscribers[t]}}};var i=function(t){return function(){console.warn("'%s' is deprecated and will be removed on next version.",t)}};return{version:"0.8.3",types:function(){var t={};if(!arguments)return t;for(var n=arguments.length,e=0;e", 6 | "scripts": { 7 | "start": "rollup --config vuelm.config.js -w", 8 | "build": "export NODE_ENV=prod && rollup --config vuelm.config.js", 9 | "test": "tape 'test/**/*_test.js' | faucet" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/keuller/vuelm.git" 14 | }, 15 | "keywords": [ 16 | "vue", 17 | "state management", 18 | "elm", 19 | "vuelm" 20 | ], 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/keuller/vuelm/issues" 24 | }, 25 | "dependencies": {}, 26 | "devDependencies": { 27 | "babel-core": "^6.26.0", 28 | "babel-plugin-external-helpers": "^6.22.0", 29 | "babel-preset-es2015-rollup": "^3.0.0", 30 | "faucet": "0.0.1", 31 | "rollup": "^0.50.0", 32 | "rollup-plugin-babel": "^3.0.2", 33 | "rollup-plugin-node-resolve": "^3.0.0", 34 | "rollup-plugin-uglify": "^2.0.1", 35 | "tape": "^4.8.0" 36 | }, 37 | "homepage": "https://github.com/keuller/vuelm#readme", 38 | "main": "index.js", 39 | "directories": { 40 | "doc": "docs", 41 | "example": "examples", 42 | "test": "test" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/connect.js: -------------------------------------------------------------------------------- 1 | import { assign_actions, deepProp } from './util.js' 2 | 3 | export default function connect(component, store) { 4 | let _bcreate = component.beforeCreate 5 | , _bdestroy = component.beforeDestroy 6 | , _bmount = component.beforeMount 7 | 8 | if (typeof store !== 'object') { 9 | console.warn('\"store\" object must be defined.') 10 | return 11 | } 12 | 13 | // inject store action into component 14 | for (let key in store) { 15 | assign_actions(component, store[key]) 16 | } 17 | 18 | component.beforeCreate = function() { 19 | let _disposes = [] 20 | 21 | let watcher = (newState) => { 22 | for(let prop in newState) { 23 | if (this.hasOwnProperty(prop)) { 24 | this.$set(this, prop, deepProp(newState, prop)) 25 | } 26 | } 27 | } 28 | 29 | for (var key in store) { 30 | _disposes.push(store[key].observe(watcher)) 31 | } 32 | 33 | if (_bcreate !== undefined) _bcreate.call(component) 34 | component.$disposes = _disposes 35 | } 36 | 37 | component.beforeDestroy = function() { 38 | if (_bdestroy !== undefined) _bdestroy() 39 | component.$disposes.forEach(dispose => dispose()) 40 | component.$disposes = null 41 | } 42 | 43 | component.beforeMount = function() { 44 | // initialize component with current state's store 45 | for (let key in store) { 46 | let tmp = store[key].state() 47 | for (let prop in tmp) { 48 | if (this.hasOwnProperty(prop)) { 49 | this.$set(this, prop, deepProp(tmp, prop)) 50 | } 51 | } 52 | } 53 | if (_bmount != undefined) _bmount() 54 | } 55 | 56 | return component 57 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import connect from './connect' 4 | import Store from './store' 5 | import { createTypes } from './util' 6 | 7 | const store = (state, updates, actions) => new Store(state, updates, actions) 8 | 9 | const deprecated = (cmd) => () => { console.warn("'%s' is deprecated and will be removed on next version.", cmd) } 10 | 11 | export default { 12 | version: '0.8.3', 13 | types: createTypes, 14 | store, 15 | info: deprecated('info'), 16 | logger: deprecated('logger'), 17 | connect 18 | } 19 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | import { deepCopy, deepProp } from './util' 2 | 3 | function Store(state, updates, actions) { 4 | updates.SYNC_MODEL = (state, data) => deepCopy(state, data) 5 | 6 | this._subscriber_id = 100 7 | this._subscribers = {} 8 | this.logger = false 9 | this._options = { 10 | state, 11 | updates 12 | } 13 | 14 | if (actions !== undefined || actions !== null) { 15 | for (let key in actions) { 16 | this[key] = actions[key] 17 | } 18 | } 19 | } 20 | 21 | Store.prototype = { 22 | _notify() { 23 | let $state = deepCopy({}, this._options.state) 24 | for(let id in this._subscribers) { 25 | this._subscribers[id]($state) 26 | } 27 | $state = null 28 | }, 29 | 30 | state() { 31 | return deepCopy({}, this._options.state) 32 | }, 33 | 34 | get(prop) { 35 | return deepProp(this._options.state, prop) 36 | }, 37 | 38 | update(type, data) { 39 | let prop = null 40 | , state = {} 41 | , prev = deepCopy({}, this._options.state) 42 | , next = {} 43 | 44 | if (this.logger && console.group) console.group(type) 45 | if (this.logger) console.log('Old State:', prev) 46 | 47 | if (typeof this._options.updates[type] === 'function') { 48 | next = this._options.updates[type].call(this, prev, data) 49 | this._options.state = next 50 | } else { 51 | next = prev 52 | } 53 | 54 | if (this.logger) console.log('New State:', next) 55 | if (this.logger && console.groupEnd) console.groupEnd() 56 | this._notify() 57 | prev = null; next = null 58 | }, 59 | 60 | observe(fn) { 61 | let self = this, $sid = this._subscriber_id++ 62 | self._subscribers[$sid] = function(state) { 63 | fn.call(self, state) 64 | } 65 | return function() { 66 | const _sid = $sid 67 | delete self._subscribers[_sid] 68 | } 69 | } 70 | } 71 | 72 | export default Store 73 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | export function deepProp(obj, path) { 2 | return path.split('.').reduce(function(o, p) { return o[p] }, obj) 3 | } 4 | 5 | export function deepCopy(target, source) { 6 | for(let prop in source) { 7 | let _val = null 8 | if (Array.isArray(source[prop])) { 9 | _val = [] 10 | source[prop].forEach(function(item) { _val.push(deepCopy({}, item)) }) 11 | } else if (typeof source[prop] === 'object') { 12 | _val = deepCopy({}, source[prop]) 13 | } else { 14 | _val = source[prop] 15 | } 16 | target[prop] = _val 17 | } 18 | return target 19 | } 20 | 21 | export function createTypes() { 22 | let result = {} 23 | if (!arguments) return result 24 | let len = arguments.length 25 | for(let idx=0; idx < len; idx++) { 26 | result[arguments[idx]] = arguments[idx].toUpperCase() 27 | } 28 | return result 29 | } 30 | 31 | export function assign_actions(component, store) { 32 | let cmethods = component.methods || {} 33 | , cname = component.name || 'unknown' 34 | , def_funcs = ['get', 'update', 'observe', '_notify'] 35 | , ctype = null 36 | 37 | let isDefaultFunc = (name) => { 38 | const has = def_funcs.filter((item) => item == name) 39 | return (has.length > 0) 40 | } 41 | 42 | for(let key in store) { 43 | ctype = (typeof store[key]) 44 | if (ctype == 'function' && !isDefaultFunc(key)) { 45 | if (cmethods.hasOwnProperty(key)) { 46 | console.warn("Component '%s' already have a method called '%s'", cname, key) 47 | } else { 48 | cmethods[key] = store[key].bind(store) 49 | } 50 | } 51 | } 52 | 53 | cmethods.sync = function(obj) { 54 | const data = JSON.parse(JSON.stringify(obj)) 55 | this.update('SYNC_MODEL', data); 56 | }.bind(store) 57 | 58 | component.methods = cmethods 59 | } 60 | -------------------------------------------------------------------------------- /test/store_test.js: -------------------------------------------------------------------------------- 1 | var Vuelm = require('../index') 2 | var test = require('tape') 3 | 4 | var Type = Vuelm.types('INCREMENT', 'DECREMENT') 5 | 6 | var state = { 7 | count: 0 8 | } 9 | 10 | var Updates = { 11 | [Type.INCREMENT]: function(state) { 12 | state.count = state.count + 1 13 | return state 14 | }, 15 | 16 | [Type.DECREMENT]: function(state) { 17 | state.count = state.count - 1 18 | return state 19 | } 20 | } 21 | 22 | var Actions = { 23 | increment: function() { 24 | this.update(Type.INCREMENT) 25 | }, 26 | decrement: function() { 27 | this.update(Type.DECREMENT) 28 | } 29 | } 30 | 31 | test('create model', function(t) { 32 | t.plan(2) 33 | 34 | var Counter = Vuelm.store(state, Updates, Actions) 35 | 36 | t.notEqual(Counter, null) 37 | t.deepEqual(Counter.state(), { count: 0 }) 38 | }) 39 | 40 | test('get property from state', function(t) { 41 | t.plan(1) 42 | 43 | var Counter = Vuelm.store(state, Updates, Actions) 44 | 45 | t.equal(Counter.get('count'), 0) 46 | }) 47 | 48 | test('Update state', function(t) { 49 | t.plan(3) 50 | 51 | var Counter = Vuelm.store(state, Updates, Actions) 52 | t.equal(Counter.get('count'), 0, 'count starts 0') 53 | 54 | Counter.increment() 55 | t.equal(Counter.get('count'), 1, 'count incremented 1') 56 | 57 | Counter.decrement() 58 | t.equal(Counter.get('count'), 0, 'count decremented 0') 59 | }) 60 | 61 | test('Observer mutations', function(t) { 62 | t.plan(1) 63 | 64 | var Counter = Vuelm.store(state, Updates, Actions) 65 | var dispose = Counter.observe(function(state) { 66 | t.deepEqual(state, { count: 1 }) 67 | }) 68 | 69 | Counter.increment() 70 | dispose() 71 | }) 72 | -------------------------------------------------------------------------------- /vuelm.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve' 2 | import babel from 'rollup-plugin-babel' 3 | import uglify from 'rollup-plugin-uglify' 4 | 5 | const config = { 6 | input: 'src/index.js', 7 | 8 | output: { 9 | file: 'index.js', 10 | format: 'umd', 11 | name: 'Vuelm' 12 | }, 13 | 14 | plugins: [ 15 | resolve({ 16 | module: true 17 | }), 18 | babel({ 19 | exclude: 'node_modules/**' 20 | }) 21 | ] 22 | } 23 | 24 | if (process.env.NODE_ENV == 'prod') { 25 | config.plugins = config.plugins.concat([ 26 | uglify({ 27 | mangle: { 28 | toplevel: true, 29 | }, 30 | warnings: false, 31 | nameCache: {} 32 | }) 33 | ]) 34 | } 35 | 36 | export default config 37 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^2.0.0: 6 | version "2.1.1" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 8 | 9 | ansi-styles@^2.2.1: 10 | version "2.2.1" 11 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 12 | 13 | babel-code-frame@^6.26.0: 14 | version "6.26.0" 15 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 16 | dependencies: 17 | chalk "^1.1.3" 18 | esutils "^2.0.2" 19 | js-tokens "^3.0.2" 20 | 21 | babel-core@^6.26.0: 22 | version "6.26.0" 23 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" 24 | dependencies: 25 | babel-code-frame "^6.26.0" 26 | babel-generator "^6.26.0" 27 | babel-helpers "^6.24.1" 28 | babel-messages "^6.23.0" 29 | babel-register "^6.26.0" 30 | babel-runtime "^6.26.0" 31 | babel-template "^6.26.0" 32 | babel-traverse "^6.26.0" 33 | babel-types "^6.26.0" 34 | babylon "^6.18.0" 35 | convert-source-map "^1.5.0" 36 | debug "^2.6.8" 37 | json5 "^0.5.1" 38 | lodash "^4.17.4" 39 | minimatch "^3.0.4" 40 | path-is-absolute "^1.0.1" 41 | private "^0.1.7" 42 | slash "^1.0.0" 43 | source-map "^0.5.6" 44 | 45 | babel-generator@^6.26.0: 46 | version "6.26.0" 47 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" 48 | dependencies: 49 | babel-messages "^6.23.0" 50 | babel-runtime "^6.26.0" 51 | babel-types "^6.26.0" 52 | detect-indent "^4.0.0" 53 | jsesc "^1.3.0" 54 | lodash "^4.17.4" 55 | source-map "^0.5.6" 56 | trim-right "^1.0.1" 57 | 58 | babel-helper-call-delegate@^6.24.1: 59 | version "6.24.1" 60 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 61 | dependencies: 62 | babel-helper-hoist-variables "^6.24.1" 63 | babel-runtime "^6.22.0" 64 | babel-traverse "^6.24.1" 65 | babel-types "^6.24.1" 66 | 67 | babel-helper-define-map@^6.24.1: 68 | version "6.26.0" 69 | resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" 70 | dependencies: 71 | babel-helper-function-name "^6.24.1" 72 | babel-runtime "^6.26.0" 73 | babel-types "^6.26.0" 74 | lodash "^4.17.4" 75 | 76 | babel-helper-function-name@^6.24.1: 77 | version "6.24.1" 78 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 79 | dependencies: 80 | babel-helper-get-function-arity "^6.24.1" 81 | babel-runtime "^6.22.0" 82 | babel-template "^6.24.1" 83 | babel-traverse "^6.24.1" 84 | babel-types "^6.24.1" 85 | 86 | babel-helper-get-function-arity@^6.24.1: 87 | version "6.24.1" 88 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 89 | dependencies: 90 | babel-runtime "^6.22.0" 91 | babel-types "^6.24.1" 92 | 93 | babel-helper-hoist-variables@^6.24.1: 94 | version "6.24.1" 95 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 96 | dependencies: 97 | babel-runtime "^6.22.0" 98 | babel-types "^6.24.1" 99 | 100 | babel-helper-optimise-call-expression@^6.24.1: 101 | version "6.24.1" 102 | resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" 103 | dependencies: 104 | babel-runtime "^6.22.0" 105 | babel-types "^6.24.1" 106 | 107 | babel-helper-regex@^6.24.1: 108 | version "6.26.0" 109 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 110 | dependencies: 111 | babel-runtime "^6.26.0" 112 | babel-types "^6.26.0" 113 | lodash "^4.17.4" 114 | 115 | babel-helper-replace-supers@^6.24.1: 116 | version "6.24.1" 117 | resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" 118 | dependencies: 119 | babel-helper-optimise-call-expression "^6.24.1" 120 | babel-messages "^6.23.0" 121 | babel-runtime "^6.22.0" 122 | babel-template "^6.24.1" 123 | babel-traverse "^6.24.1" 124 | babel-types "^6.24.1" 125 | 126 | babel-helpers@^6.24.1: 127 | version "6.24.1" 128 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 129 | dependencies: 130 | babel-runtime "^6.22.0" 131 | babel-template "^6.24.1" 132 | 133 | babel-messages@^6.23.0: 134 | version "6.23.0" 135 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 136 | dependencies: 137 | babel-runtime "^6.22.0" 138 | 139 | babel-plugin-check-es2015-constants@^6.22.0: 140 | version "6.22.0" 141 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 142 | dependencies: 143 | babel-runtime "^6.22.0" 144 | 145 | babel-plugin-external-helpers@^6.18.0, babel-plugin-external-helpers@^6.22.0: 146 | version "6.22.0" 147 | resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" 148 | dependencies: 149 | babel-runtime "^6.22.0" 150 | 151 | babel-plugin-transform-es2015-arrow-functions@^6.22.0: 152 | version "6.22.0" 153 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" 154 | dependencies: 155 | babel-runtime "^6.22.0" 156 | 157 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: 158 | version "6.22.0" 159 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" 160 | dependencies: 161 | babel-runtime "^6.22.0" 162 | 163 | babel-plugin-transform-es2015-block-scoping@^6.24.1: 164 | version "6.26.0" 165 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 166 | dependencies: 167 | babel-runtime "^6.26.0" 168 | babel-template "^6.26.0" 169 | babel-traverse "^6.26.0" 170 | babel-types "^6.26.0" 171 | lodash "^4.17.4" 172 | 173 | babel-plugin-transform-es2015-classes@^6.24.1: 174 | version "6.24.1" 175 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" 176 | dependencies: 177 | babel-helper-define-map "^6.24.1" 178 | babel-helper-function-name "^6.24.1" 179 | babel-helper-optimise-call-expression "^6.24.1" 180 | babel-helper-replace-supers "^6.24.1" 181 | babel-messages "^6.23.0" 182 | babel-runtime "^6.22.0" 183 | babel-template "^6.24.1" 184 | babel-traverse "^6.24.1" 185 | babel-types "^6.24.1" 186 | 187 | babel-plugin-transform-es2015-computed-properties@^6.24.1: 188 | version "6.24.1" 189 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" 190 | dependencies: 191 | babel-runtime "^6.22.0" 192 | babel-template "^6.24.1" 193 | 194 | babel-plugin-transform-es2015-destructuring@^6.22.0: 195 | version "6.23.0" 196 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 197 | dependencies: 198 | babel-runtime "^6.22.0" 199 | 200 | babel-plugin-transform-es2015-duplicate-keys@^6.24.1: 201 | version "6.24.1" 202 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" 203 | dependencies: 204 | babel-runtime "^6.22.0" 205 | babel-types "^6.24.1" 206 | 207 | babel-plugin-transform-es2015-for-of@^6.22.0: 208 | version "6.23.0" 209 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" 210 | dependencies: 211 | babel-runtime "^6.22.0" 212 | 213 | babel-plugin-transform-es2015-function-name@^6.24.1: 214 | version "6.24.1" 215 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 216 | dependencies: 217 | babel-helper-function-name "^6.24.1" 218 | babel-runtime "^6.22.0" 219 | babel-types "^6.24.1" 220 | 221 | babel-plugin-transform-es2015-literals@^6.22.0: 222 | version "6.22.0" 223 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" 224 | dependencies: 225 | babel-runtime "^6.22.0" 226 | 227 | babel-plugin-transform-es2015-modules-amd@^6.24.1: 228 | version "6.24.1" 229 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" 230 | dependencies: 231 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 232 | babel-runtime "^6.22.0" 233 | babel-template "^6.24.1" 234 | 235 | babel-plugin-transform-es2015-modules-commonjs@^6.24.1: 236 | version "6.26.0" 237 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" 238 | dependencies: 239 | babel-plugin-transform-strict-mode "^6.24.1" 240 | babel-runtime "^6.26.0" 241 | babel-template "^6.26.0" 242 | babel-types "^6.26.0" 243 | 244 | babel-plugin-transform-es2015-modules-systemjs@^6.24.1: 245 | version "6.24.1" 246 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" 247 | dependencies: 248 | babel-helper-hoist-variables "^6.24.1" 249 | babel-runtime "^6.22.0" 250 | babel-template "^6.24.1" 251 | 252 | babel-plugin-transform-es2015-modules-umd@^6.24.1: 253 | version "6.24.1" 254 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" 255 | dependencies: 256 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 257 | babel-runtime "^6.22.0" 258 | babel-template "^6.24.1" 259 | 260 | babel-plugin-transform-es2015-object-super@^6.24.1: 261 | version "6.24.1" 262 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" 263 | dependencies: 264 | babel-helper-replace-supers "^6.24.1" 265 | babel-runtime "^6.22.0" 266 | 267 | babel-plugin-transform-es2015-parameters@^6.24.1: 268 | version "6.24.1" 269 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 270 | dependencies: 271 | babel-helper-call-delegate "^6.24.1" 272 | babel-helper-get-function-arity "^6.24.1" 273 | babel-runtime "^6.22.0" 274 | babel-template "^6.24.1" 275 | babel-traverse "^6.24.1" 276 | babel-types "^6.24.1" 277 | 278 | babel-plugin-transform-es2015-shorthand-properties@^6.24.1: 279 | version "6.24.1" 280 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" 281 | dependencies: 282 | babel-runtime "^6.22.0" 283 | babel-types "^6.24.1" 284 | 285 | babel-plugin-transform-es2015-spread@^6.22.0: 286 | version "6.22.0" 287 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 288 | dependencies: 289 | babel-runtime "^6.22.0" 290 | 291 | babel-plugin-transform-es2015-sticky-regex@^6.24.1: 292 | version "6.24.1" 293 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 294 | dependencies: 295 | babel-helper-regex "^6.24.1" 296 | babel-runtime "^6.22.0" 297 | babel-types "^6.24.1" 298 | 299 | babel-plugin-transform-es2015-template-literals@^6.22.0: 300 | version "6.22.0" 301 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" 302 | dependencies: 303 | babel-runtime "^6.22.0" 304 | 305 | babel-plugin-transform-es2015-typeof-symbol@^6.22.0: 306 | version "6.23.0" 307 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" 308 | dependencies: 309 | babel-runtime "^6.22.0" 310 | 311 | babel-plugin-transform-es2015-unicode-regex@^6.24.1: 312 | version "6.24.1" 313 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 314 | dependencies: 315 | babel-helper-regex "^6.24.1" 316 | babel-runtime "^6.22.0" 317 | regexpu-core "^2.0.0" 318 | 319 | babel-plugin-transform-regenerator@^6.24.1: 320 | version "6.26.0" 321 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" 322 | dependencies: 323 | regenerator-transform "^0.10.0" 324 | 325 | babel-plugin-transform-strict-mode@^6.24.1: 326 | version "6.24.1" 327 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 328 | dependencies: 329 | babel-runtime "^6.22.0" 330 | babel-types "^6.24.1" 331 | 332 | babel-preset-es2015-rollup@^3.0.0: 333 | version "3.0.0" 334 | resolved "https://registry.yarnpkg.com/babel-preset-es2015-rollup/-/babel-preset-es2015-rollup-3.0.0.tgz#854b63ecde2ee98cac40e882f67bfcf185b1f24a" 335 | dependencies: 336 | babel-plugin-external-helpers "^6.18.0" 337 | babel-preset-es2015 "^6.3.13" 338 | require-relative "^0.8.7" 339 | 340 | babel-preset-es2015@^6.3.13: 341 | version "6.24.1" 342 | resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" 343 | dependencies: 344 | babel-plugin-check-es2015-constants "^6.22.0" 345 | babel-plugin-transform-es2015-arrow-functions "^6.22.0" 346 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" 347 | babel-plugin-transform-es2015-block-scoping "^6.24.1" 348 | babel-plugin-transform-es2015-classes "^6.24.1" 349 | babel-plugin-transform-es2015-computed-properties "^6.24.1" 350 | babel-plugin-transform-es2015-destructuring "^6.22.0" 351 | babel-plugin-transform-es2015-duplicate-keys "^6.24.1" 352 | babel-plugin-transform-es2015-for-of "^6.22.0" 353 | babel-plugin-transform-es2015-function-name "^6.24.1" 354 | babel-plugin-transform-es2015-literals "^6.22.0" 355 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 356 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 357 | babel-plugin-transform-es2015-modules-systemjs "^6.24.1" 358 | babel-plugin-transform-es2015-modules-umd "^6.24.1" 359 | babel-plugin-transform-es2015-object-super "^6.24.1" 360 | babel-plugin-transform-es2015-parameters "^6.24.1" 361 | babel-plugin-transform-es2015-shorthand-properties "^6.24.1" 362 | babel-plugin-transform-es2015-spread "^6.22.0" 363 | babel-plugin-transform-es2015-sticky-regex "^6.24.1" 364 | babel-plugin-transform-es2015-template-literals "^6.22.0" 365 | babel-plugin-transform-es2015-typeof-symbol "^6.22.0" 366 | babel-plugin-transform-es2015-unicode-regex "^6.24.1" 367 | babel-plugin-transform-regenerator "^6.24.1" 368 | 369 | babel-register@^6.26.0: 370 | version "6.26.0" 371 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 372 | dependencies: 373 | babel-core "^6.26.0" 374 | babel-runtime "^6.26.0" 375 | core-js "^2.5.0" 376 | home-or-tmp "^2.0.0" 377 | lodash "^4.17.4" 378 | mkdirp "^0.5.1" 379 | source-map-support "^0.4.15" 380 | 381 | babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: 382 | version "6.26.0" 383 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 384 | dependencies: 385 | core-js "^2.4.0" 386 | regenerator-runtime "^0.11.0" 387 | 388 | babel-template@^6.24.1, babel-template@^6.26.0: 389 | version "6.26.0" 390 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 391 | dependencies: 392 | babel-runtime "^6.26.0" 393 | babel-traverse "^6.26.0" 394 | babel-types "^6.26.0" 395 | babylon "^6.18.0" 396 | lodash "^4.17.4" 397 | 398 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 399 | version "6.26.0" 400 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 401 | dependencies: 402 | babel-code-frame "^6.26.0" 403 | babel-messages "^6.23.0" 404 | babel-runtime "^6.26.0" 405 | babel-types "^6.26.0" 406 | babylon "^6.18.0" 407 | debug "^2.6.8" 408 | globals "^9.18.0" 409 | invariant "^2.2.2" 410 | lodash "^4.17.4" 411 | 412 | babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: 413 | version "6.26.0" 414 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 415 | dependencies: 416 | babel-runtime "^6.26.0" 417 | esutils "^2.0.2" 418 | lodash "^4.17.4" 419 | to-fast-properties "^1.0.3" 420 | 421 | babylon@^6.18.0: 422 | version "6.18.0" 423 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 424 | 425 | balanced-match@^1.0.0: 426 | version "1.0.0" 427 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 428 | 429 | brace-expansion@^1.1.7: 430 | version "1.1.8" 431 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" 432 | dependencies: 433 | balanced-match "^1.0.0" 434 | concat-map "0.0.1" 435 | 436 | browser-resolve@^1.11.0: 437 | version "1.11.2" 438 | resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" 439 | dependencies: 440 | resolve "1.1.7" 441 | 442 | builtin-modules@^1.1.0: 443 | version "1.1.1" 444 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 445 | 446 | chalk@^1.1.3: 447 | version "1.1.3" 448 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 449 | dependencies: 450 | ansi-styles "^2.2.1" 451 | escape-string-regexp "^1.0.2" 452 | has-ansi "^2.0.0" 453 | strip-ansi "^3.0.0" 454 | supports-color "^2.0.0" 455 | 456 | commander@~2.11.0: 457 | version "2.11.0" 458 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" 459 | 460 | concat-map@0.0.1: 461 | version "0.0.1" 462 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 463 | 464 | convert-source-map@^1.5.0: 465 | version "1.5.0" 466 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" 467 | 468 | core-js@^2.4.0, core-js@^2.5.0: 469 | version "2.5.1" 470 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" 471 | 472 | core-util-is@~1.0.0: 473 | version "1.0.2" 474 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 475 | 476 | debug@^2.6.8: 477 | version "2.6.9" 478 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 479 | dependencies: 480 | ms "2.0.0" 481 | 482 | deep-equal@~0.1.0: 483 | version "0.1.2" 484 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.1.2.tgz#b246c2b80a570a47c11be1d9bd1070ec878b87ce" 485 | 486 | deep-equal@~1.0.1: 487 | version "1.0.1" 488 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 489 | 490 | define-properties@^1.1.2: 491 | version "1.1.2" 492 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" 493 | dependencies: 494 | foreach "^2.0.5" 495 | object-keys "^1.0.8" 496 | 497 | defined@0.0.0, defined@~0.0.0: 498 | version "0.0.0" 499 | resolved "https://registry.yarnpkg.com/defined/-/defined-0.0.0.tgz#f35eea7d705e933baf13b2f03b3f83d921403b3e" 500 | 501 | defined@~1.0.0: 502 | version "1.0.0" 503 | resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" 504 | 505 | detect-indent@^4.0.0: 506 | version "4.0.0" 507 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 508 | dependencies: 509 | repeating "^2.0.0" 510 | 511 | duplexer@~0.1.1: 512 | version "0.1.1" 513 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" 514 | 515 | es-abstract@^1.5.0: 516 | version "1.9.0" 517 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" 518 | dependencies: 519 | es-to-primitive "^1.1.1" 520 | function-bind "^1.1.1" 521 | has "^1.0.1" 522 | is-callable "^1.1.3" 523 | is-regex "^1.0.4" 524 | 525 | es-to-primitive@^1.1.1: 526 | version "1.1.1" 527 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" 528 | dependencies: 529 | is-callable "^1.1.1" 530 | is-date-object "^1.0.1" 531 | is-symbol "^1.0.1" 532 | 533 | escape-string-regexp@^1.0.2: 534 | version "1.0.5" 535 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 536 | 537 | estree-walker@^0.2.1: 538 | version "0.2.1" 539 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" 540 | 541 | esutils@^2.0.2: 542 | version "2.0.2" 543 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 544 | 545 | faucet@0.0.1: 546 | version "0.0.1" 547 | resolved "https://registry.yarnpkg.com/faucet/-/faucet-0.0.1.tgz#597dcf1d2189a2c062321b591e8f151ed2039d9c" 548 | dependencies: 549 | defined "0.0.0" 550 | duplexer "~0.1.1" 551 | minimist "0.0.5" 552 | sprintf "~0.1.3" 553 | tap-parser "~0.4.0" 554 | tape "~2.3.2" 555 | through2 "~0.2.3" 556 | 557 | for-each@~0.3.2: 558 | version "0.3.2" 559 | resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" 560 | dependencies: 561 | is-function "~1.0.0" 562 | 563 | foreach@^2.0.5: 564 | version "2.0.5" 565 | resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" 566 | 567 | fs.realpath@^1.0.0: 568 | version "1.0.0" 569 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 570 | 571 | function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.0: 572 | version "1.1.1" 573 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 574 | 575 | glob@~7.1.2: 576 | version "7.1.2" 577 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 578 | dependencies: 579 | fs.realpath "^1.0.0" 580 | inflight "^1.0.4" 581 | inherits "2" 582 | minimatch "^3.0.4" 583 | once "^1.3.0" 584 | path-is-absolute "^1.0.0" 585 | 586 | globals@^9.18.0: 587 | version "9.18.0" 588 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 589 | 590 | has-ansi@^2.0.0: 591 | version "2.0.0" 592 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 593 | dependencies: 594 | ansi-regex "^2.0.0" 595 | 596 | has@^1.0.1, has@~1.0.1: 597 | version "1.0.1" 598 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" 599 | dependencies: 600 | function-bind "^1.0.2" 601 | 602 | home-or-tmp@^2.0.0: 603 | version "2.0.0" 604 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 605 | dependencies: 606 | os-homedir "^1.0.0" 607 | os-tmpdir "^1.0.1" 608 | 609 | inflight@^1.0.4: 610 | version "1.0.6" 611 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 612 | dependencies: 613 | once "^1.3.0" 614 | wrappy "1" 615 | 616 | inherits@2, inherits@~2.0.1, inherits@~2.0.3: 617 | version "2.0.3" 618 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 619 | 620 | invariant@^2.2.2: 621 | version "2.2.2" 622 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" 623 | dependencies: 624 | loose-envify "^1.0.0" 625 | 626 | is-callable@^1.1.1, is-callable@^1.1.3: 627 | version "1.1.3" 628 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" 629 | 630 | is-date-object@^1.0.1: 631 | version "1.0.1" 632 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 633 | 634 | is-finite@^1.0.0: 635 | version "1.0.2" 636 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 637 | dependencies: 638 | number-is-nan "^1.0.0" 639 | 640 | is-function@~1.0.0: 641 | version "1.0.1" 642 | resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" 643 | 644 | is-module@^1.0.0: 645 | version "1.0.0" 646 | resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" 647 | 648 | is-regex@^1.0.4: 649 | version "1.0.4" 650 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 651 | dependencies: 652 | has "^1.0.1" 653 | 654 | is-symbol@^1.0.1: 655 | version "1.0.1" 656 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" 657 | 658 | isarray@0.0.1: 659 | version "0.0.1" 660 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 661 | 662 | js-tokens@^3.0.0, js-tokens@^3.0.2: 663 | version "3.0.2" 664 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 665 | 666 | jsesc@^1.3.0: 667 | version "1.3.0" 668 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 669 | 670 | jsesc@~0.5.0: 671 | version "0.5.0" 672 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 673 | 674 | json5@^0.5.1: 675 | version "0.5.1" 676 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 677 | 678 | jsonify@~0.0.0: 679 | version "0.0.0" 680 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 681 | 682 | lodash@^4.17.4: 683 | version "4.17.4" 684 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 685 | 686 | loose-envify@^1.0.0: 687 | version "1.3.1" 688 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 689 | dependencies: 690 | js-tokens "^3.0.0" 691 | 692 | minimatch@^3.0.2, minimatch@^3.0.4: 693 | version "3.0.4" 694 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 695 | dependencies: 696 | brace-expansion "^1.1.7" 697 | 698 | minimist@0.0.5: 699 | version "0.0.5" 700 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.5.tgz#d7aa327bcecf518f9106ac6b8f003fa3bcea8566" 701 | 702 | minimist@0.0.8: 703 | version "0.0.8" 704 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 705 | 706 | minimist@~1.2.0: 707 | version "1.2.0" 708 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 709 | 710 | mkdirp@^0.5.1: 711 | version "0.5.1" 712 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 713 | dependencies: 714 | minimist "0.0.8" 715 | 716 | ms@2.0.0: 717 | version "2.0.0" 718 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 719 | 720 | number-is-nan@^1.0.0: 721 | version "1.0.1" 722 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 723 | 724 | object-inspect@~1.3.0: 725 | version "1.3.0" 726 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d" 727 | 728 | object-keys@^1.0.8: 729 | version "1.0.11" 730 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" 731 | 732 | object-keys@~0.4.0: 733 | version "0.4.0" 734 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" 735 | 736 | once@^1.3.0: 737 | version "1.4.0" 738 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 739 | dependencies: 740 | wrappy "1" 741 | 742 | os-homedir@^1.0.0: 743 | version "1.0.2" 744 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 745 | 746 | os-tmpdir@^1.0.1: 747 | version "1.0.2" 748 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 749 | 750 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 751 | version "1.0.1" 752 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 753 | 754 | path-parse@^1.0.5: 755 | version "1.0.5" 756 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 757 | 758 | private@^0.1.6, private@^0.1.7: 759 | version "0.1.7" 760 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" 761 | 762 | readable-stream@~1.1.11, readable-stream@~1.1.9: 763 | version "1.1.14" 764 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" 765 | dependencies: 766 | core-util-is "~1.0.0" 767 | inherits "~2.0.1" 768 | isarray "0.0.1" 769 | string_decoder "~0.10.x" 770 | 771 | regenerate@^1.2.1: 772 | version "1.3.3" 773 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" 774 | 775 | regenerator-runtime@^0.11.0: 776 | version "0.11.0" 777 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" 778 | 779 | regenerator-transform@^0.10.0: 780 | version "0.10.1" 781 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" 782 | dependencies: 783 | babel-runtime "^6.18.0" 784 | babel-types "^6.19.0" 785 | private "^0.1.6" 786 | 787 | regexpu-core@^2.0.0: 788 | version "2.0.0" 789 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 790 | dependencies: 791 | regenerate "^1.2.1" 792 | regjsgen "^0.2.0" 793 | regjsparser "^0.1.4" 794 | 795 | regjsgen@^0.2.0: 796 | version "0.2.0" 797 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 798 | 799 | regjsparser@^0.1.4: 800 | version "0.1.5" 801 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 802 | dependencies: 803 | jsesc "~0.5.0" 804 | 805 | repeating@^2.0.0: 806 | version "2.0.1" 807 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 808 | dependencies: 809 | is-finite "^1.0.0" 810 | 811 | require-relative@^0.8.7: 812 | version "0.8.7" 813 | resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" 814 | 815 | resolve@1.1.7: 816 | version "1.1.7" 817 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" 818 | 819 | resolve@^1.1.6, resolve@~1.4.0: 820 | version "1.4.0" 821 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" 822 | dependencies: 823 | path-parse "^1.0.5" 824 | 825 | resumer@~0.0.0: 826 | version "0.0.0" 827 | resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" 828 | dependencies: 829 | through "~2.3.4" 830 | 831 | rollup-plugin-babel@^3.0.2: 832 | version "3.0.2" 833 | resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.2.tgz#a2765dea0eaa8aece351c983573300d17497495b" 834 | dependencies: 835 | rollup-pluginutils "^1.5.0" 836 | 837 | rollup-plugin-node-resolve@^3.0.0: 838 | version "3.0.0" 839 | resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.0.tgz#8b897c4c3030d5001277b0514b25d2ca09683ee0" 840 | dependencies: 841 | browser-resolve "^1.11.0" 842 | builtin-modules "^1.1.0" 843 | is-module "^1.0.0" 844 | resolve "^1.1.6" 845 | 846 | rollup-plugin-uglify@^2.0.1: 847 | version "2.0.1" 848 | resolved "https://registry.yarnpkg.com/rollup-plugin-uglify/-/rollup-plugin-uglify-2.0.1.tgz#67b37ad1efdafbd83af4c36b40c189ee4866c969" 849 | dependencies: 850 | uglify-js "^3.0.9" 851 | 852 | rollup-pluginutils@^1.5.0: 853 | version "1.5.2" 854 | resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" 855 | dependencies: 856 | estree-walker "^0.2.1" 857 | minimatch "^3.0.2" 858 | 859 | rollup@^0.50.0: 860 | version "0.50.0" 861 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.50.0.tgz#4c158f4e780e6cb33ff0dbfc184a52cc58cd5f3b" 862 | 863 | slash@^1.0.0: 864 | version "1.0.0" 865 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 866 | 867 | source-map-support@^0.4.15: 868 | version "0.4.18" 869 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 870 | dependencies: 871 | source-map "^0.5.6" 872 | 873 | source-map@^0.5.6, source-map@~0.5.1: 874 | version "0.5.7" 875 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 876 | 877 | sprintf@~0.1.3: 878 | version "0.1.5" 879 | resolved "https://registry.yarnpkg.com/sprintf/-/sprintf-0.1.5.tgz#8f83e39a9317c1a502cb7db8050e51c679f6edcf" 880 | 881 | string.prototype.trim@~1.1.2: 882 | version "1.1.2" 883 | resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" 884 | dependencies: 885 | define-properties "^1.1.2" 886 | es-abstract "^1.5.0" 887 | function-bind "^1.0.2" 888 | 889 | string_decoder@~0.10.x: 890 | version "0.10.31" 891 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 892 | 893 | strip-ansi@^3.0.0: 894 | version "3.0.1" 895 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 896 | dependencies: 897 | ansi-regex "^2.0.0" 898 | 899 | supports-color@^2.0.0: 900 | version "2.0.0" 901 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 902 | 903 | tap-parser@~0.4.0: 904 | version "0.4.3" 905 | resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-0.4.3.tgz#a4eae190c10d76c7a111921ff38bbe4d58f09eea" 906 | dependencies: 907 | inherits "~2.0.1" 908 | readable-stream "~1.1.11" 909 | 910 | tape@^4.8.0: 911 | version "4.8.0" 912 | resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e" 913 | dependencies: 914 | deep-equal "~1.0.1" 915 | defined "~1.0.0" 916 | for-each "~0.3.2" 917 | function-bind "~1.1.0" 918 | glob "~7.1.2" 919 | has "~1.0.1" 920 | inherits "~2.0.3" 921 | minimist "~1.2.0" 922 | object-inspect "~1.3.0" 923 | resolve "~1.4.0" 924 | resumer "~0.0.0" 925 | string.prototype.trim "~1.1.2" 926 | through "~2.3.8" 927 | 928 | tape@~2.3.2: 929 | version "2.3.3" 930 | resolved "https://registry.yarnpkg.com/tape/-/tape-2.3.3.tgz#2e7ce0a31df09f8d6851664a71842e0ca5057af7" 931 | dependencies: 932 | deep-equal "~0.1.0" 933 | defined "~0.0.0" 934 | inherits "~2.0.1" 935 | jsonify "~0.0.0" 936 | resumer "~0.0.0" 937 | through "~2.3.4" 938 | 939 | through2@~0.2.3: 940 | version "0.2.3" 941 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" 942 | dependencies: 943 | readable-stream "~1.1.9" 944 | xtend "~2.1.1" 945 | 946 | through@~2.3.4, through@~2.3.8: 947 | version "2.3.8" 948 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 949 | 950 | to-fast-properties@^1.0.3: 951 | version "1.0.3" 952 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 953 | 954 | trim-right@^1.0.1: 955 | version "1.0.1" 956 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 957 | 958 | uglify-js@^3.0.9: 959 | version "3.1.3" 960 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.1.3.tgz#d61f0453b4718cab01581f3162aa90bab7520b42" 961 | dependencies: 962 | commander "~2.11.0" 963 | source-map "~0.5.1" 964 | 965 | wrappy@1: 966 | version "1.0.2" 967 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 968 | 969 | xtend@~2.1.1: 970 | version "2.1.2" 971 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" 972 | dependencies: 973 | object-keys "~0.4.0" 974 | --------------------------------------------------------------------------------