breezy 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/assets/javascript/breezy.js +6067 -0
- data/lib/breezy.rb +0 -7
- data/lib/breezy/configuration.rb +9 -3
- data/lib/breezy/helpers.rb +1 -1
- data/lib/breezy/render.rb +1 -1
- data/lib/breezy/version.rb +1 -1
- data/lib/generators/breezy/view/templates/view.js +17 -0
- data/lib/generators/breezy/view/templates/view.js.breezy +2 -0
- data/lib/generators/breezy/view/templates/view.jsx +21 -0
- data/lib/generators/breezy/view/view_generator.rb +40 -7
- data/lib/install/mobile.rb +54 -0
- data/lib/install/templates/mobile/app.js +84 -0
- data/lib/install/templates/mobile/app.json +6 -0
- data/lib/install/templates/mobile/package.json +32 -0
- data/lib/install/templates/mobile/rn-cli.config.js +4 -0
- data/lib/install/templates/web/application.js +62 -0
- data/lib/install/web.rb +72 -0
- data/lib/tasks/install.rake +46 -0
- data/test/render_test.rb +2 -2
- data/test/test_helper.rb +2 -0
- metadata +37 -48
- data/README.md +0 -338
- data/lib/assets/javascripts/breezy.coffee +0 -4
- data/lib/assets/javascripts/breezy/component_url.coffee +0 -61
- data/lib/assets/javascripts/breezy/controller.coffee +0 -197
- data/lib/assets/javascripts/breezy/csrf_token.coffee +0 -9
- data/lib/assets/javascripts/breezy/doubly_linked_list.coffee +0 -57
- data/lib/assets/javascripts/breezy/parallel_queue.coffee +0 -35
- data/lib/assets/javascripts/breezy/progress_bar.coffee +0 -139
- data/lib/assets/javascripts/breezy/remote.coffee +0 -136
- data/lib/assets/javascripts/breezy/snapshot.coffee +0 -100
- data/lib/assets/javascripts/breezy/start.coffee +0 -60
- data/lib/assets/javascripts/breezy/utils.coffee +0 -174
- data/lib/breezy/active_support.rb +0 -21
- data/lib/breezy_template.rb +0 -320
- data/lib/breezy_template/deferment_extension.rb +0 -48
- data/lib/breezy_template/dependency_tracker.rb +0 -47
- data/lib/breezy_template/digestor.rb +0 -30
- data/lib/breezy_template/handler.rb +0 -43
- data/lib/breezy_template/partial_extension.rb +0 -87
- data/lib/breezy_template/search_extension.rb +0 -108
- data/lib/generators/breezy/install/install_generator.rb +0 -61
- data/lib/generators/breezy/install/templates/Default.js.jsx +0 -7
- data/lib/generators/breezy/install/templates/View.js.jsx +0 -7
- data/lib/generators/breezy/install/templates/boot.js +0 -5
- data/lib/generators/breezy/view/templates/view.js.jsx +0 -8
- data/test/blade_helper.rb +0 -22
- data/test/breezy_template_test.rb +0 -1095
- data/test/dependency_tracker_test.rb +0 -66
data/lib/breezy.rb
CHANGED
@@ -7,7 +7,6 @@ require 'breezy/x_domain_blocker'
|
|
7
7
|
require 'breezy/render'
|
8
8
|
require 'breezy/helpers'
|
9
9
|
require 'breezy/configuration'
|
10
|
-
require 'breezy_template'
|
11
10
|
|
12
11
|
module Breezy
|
13
12
|
module Controller
|
@@ -55,12 +54,6 @@ module Breezy
|
|
55
54
|
ActionDispatch::Routing::Redirect.class_eval do
|
56
55
|
prepend XHRRedirect
|
57
56
|
end
|
58
|
-
end
|
59
|
-
|
60
|
-
ActiveSupport.on_load(:action_view) do
|
61
|
-
ActionView::Template.register_template_handler :breezy, BreezyTemplate::Handler
|
62
|
-
require 'breezy_template/dependency_tracker'
|
63
|
-
require 'breezy/active_support'
|
64
57
|
|
65
58
|
(ActionView::RoutingUrlFor rescue ActionView::Helpers::UrlHelper).module_eval do
|
66
59
|
prepend XHRUrlFor
|
data/lib/breezy/configuration.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
module Breezy
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :track_assets
|
4
|
-
|
5
3
|
def initialize
|
6
|
-
|
4
|
+
BreezyTemplate.configuration = nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def track_assets=(assets)
|
8
|
+
BreezyTemplate.configuration.track_assets = assets
|
9
|
+
end
|
10
|
+
|
11
|
+
def track_assets
|
12
|
+
BreezyTemplate.configuration.track_assets
|
7
13
|
end
|
8
14
|
end
|
9
15
|
|
data/lib/breezy/helpers.rb
CHANGED
data/lib/breezy/render.rb
CHANGED
@@ -17,7 +17,7 @@ module Breezy
|
|
17
17
|
view_parts = _prefixes.reverse.push(action_name)[1..-1]
|
18
18
|
view_name = view_parts.map(&:camelize).join
|
19
19
|
|
20
|
-
breezy[:
|
20
|
+
breezy[:screen] ||= view_name
|
21
21
|
render_options[:locals] ||= {}
|
22
22
|
render_options[:locals][:breezy] = breezy
|
23
23
|
end
|
data/lib/breezy/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
|
+
import { connect } from 'react-redux'
|
4
|
+
|
5
|
+
class <%= @js_filename %> extends React.Component {
|
6
|
+
render () {
|
7
|
+
return (
|
8
|
+
<div> {this.props.greetings}
|
9
|
+
</div>
|
10
|
+
)
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
export default connect(
|
15
|
+
mapStateToProps,
|
16
|
+
mapDispatchToProps
|
17
|
+
)(<%= @js_filename %>)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
|
+
import { connect } from 'react-redux'
|
4
|
+
import {View, Text} from 'react-native'
|
5
|
+
|
6
|
+
class <%= @js_filename %> extends React.Component {
|
7
|
+
render () {
|
8
|
+
return (
|
9
|
+
<View>
|
10
|
+
<Text>
|
11
|
+
{this.props.greetings}
|
12
|
+
</Text>
|
13
|
+
</View>
|
14
|
+
)
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
export default connect(
|
19
|
+
mapStateToProps,
|
20
|
+
mapDispatchToProps
|
21
|
+
)(<%= @js_filename %>)
|
@@ -5,6 +5,13 @@ module Breezy
|
|
5
5
|
Description:
|
6
6
|
Creates a content view and jsx view.
|
7
7
|
DESC
|
8
|
+
class_option :target,
|
9
|
+
aliases: '-t',
|
10
|
+
type: :string,
|
11
|
+
default: 'web',
|
12
|
+
desc: 'Specify target platform',
|
13
|
+
enum: ['web', 'mobile']
|
14
|
+
|
8
15
|
argument :actions, type: :array, default: [], banner: "action action"
|
9
16
|
|
10
17
|
def self.source_root
|
@@ -13,23 +20,49 @@ DESC
|
|
13
20
|
|
14
21
|
def copy_view_files
|
15
22
|
base_parts = class_path + [file_name]
|
16
|
-
|
17
|
-
view_destination = "app/assets/javascripts/views"
|
23
|
+
destination = File.join("app/views", base_parts)
|
18
24
|
|
19
|
-
empty_directory content_destination
|
20
|
-
empty_directory view_destination
|
21
25
|
|
22
26
|
actions.each do |action|
|
23
27
|
@action = action
|
24
28
|
@js_filename = (base_parts + [action]).map(&:camelcase).join
|
25
|
-
@content_path = File.join(
|
26
|
-
|
29
|
+
@content_path = File.join(destination, "#{@action}.js.props")
|
30
|
+
|
31
|
+
if options[:target] == 'mobile'
|
32
|
+
@view_ext = 'jsx'
|
33
|
+
else
|
34
|
+
@view_ext = 'js'
|
35
|
+
end
|
27
36
|
|
28
|
-
|
37
|
+
@view_path = File.join(destination, "#{@action}.#{@view_ext}")
|
38
|
+
|
39
|
+
template "view.#{@view_ext}", @view_path
|
29
40
|
template 'view.js.breezy', @content_path
|
30
41
|
end
|
31
42
|
end
|
32
43
|
|
44
|
+
def append_mapping
|
45
|
+
if options[:platform] == 'mobile'
|
46
|
+
app_js = 'app/javascript/packs/application.js'
|
47
|
+
else
|
48
|
+
app_js = 'App.js'
|
49
|
+
end
|
50
|
+
|
51
|
+
base_parts = class_path + [file_name]
|
52
|
+
destination = File.join("views", base_parts)
|
53
|
+
|
54
|
+
actions.each do |action|
|
55
|
+
@js_filename = (base_parts + [action]).map(&:camelcase).join
|
56
|
+
|
57
|
+
inject_into_file app_js, after: "from '@jho406/breezy'" do
|
58
|
+
"\nimport #{@js_filename} from '#{destination}/#{action}'"
|
59
|
+
end
|
60
|
+
|
61
|
+
inject_into_file app_js, after: 'const mapping = {' do
|
62
|
+
"\n #{@js_filename},"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
33
66
|
end
|
34
67
|
end
|
35
68
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
babelrc = Rails.root.join(".babelrc")
|
2
|
+
|
3
|
+
if File.exist?(babelrc)
|
4
|
+
react_babelrc = JSON.parse(File.read(babelrc))
|
5
|
+
react_babelrc["presets"] ||= []
|
6
|
+
react_babelrc["plugins"] ||= []
|
7
|
+
|
8
|
+
if !react_babelrc["presets"].include?("react")
|
9
|
+
react_babelrc["presets"].push("react")
|
10
|
+
say "Copying react preset to your .babelrc file"
|
11
|
+
|
12
|
+
File.open(babelrc, "w") do |f|
|
13
|
+
f.puts JSON.pretty_generate(react_babelrc)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if !react_babelrc["plugins"].any?{|plugin| Array(plugin).include?("module-resolver")}
|
18
|
+
react_babelrc["plugins"].push(["module-resolver", {
|
19
|
+
"root": ["./app"],
|
20
|
+
"alias": {
|
21
|
+
"views": "./app/views",
|
22
|
+
"components": "./app/components",
|
23
|
+
"javascripts": "./app/javascripts"
|
24
|
+
}
|
25
|
+
}])
|
26
|
+
|
27
|
+
say "Copying module-resolver preset to your .babelrc file"
|
28
|
+
|
29
|
+
File.open(babelrc, "w") do |f|
|
30
|
+
f.puts JSON.pretty_generate(react_babelrc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
else
|
35
|
+
say "Copying .babelrc to app root"
|
36
|
+
copy_file "#{__dir__}/templates/mobile/.babelrc", Rails.root.join(".babelrc")
|
37
|
+
end
|
38
|
+
|
39
|
+
say "Copying application.js file to app root"
|
40
|
+
copy_file "#{__dir__}/templates/mobile/app.js", Rails.root.join("App.js")
|
41
|
+
|
42
|
+
say "Copying rn-cli.config.js file to app root"
|
43
|
+
copy_file "#{__dir__}/templates/mobile/rn-cli.config.js", Rails.root.join("rn-cli.config.js")
|
44
|
+
|
45
|
+
say "Copying app.json expo file to app root"
|
46
|
+
copy_file "#{__dir__}/templates/mobile/app.json", Rails.root.join("app.json")
|
47
|
+
|
48
|
+
say "Copying package.json expo file to app root"
|
49
|
+
copy_file "#{__dir__}/templates/mobile/package.json", Rails.root.join("package.json")
|
50
|
+
|
51
|
+
say "Installing all breezy dependencies"
|
52
|
+
run "yarn"
|
53
|
+
|
54
|
+
say "Rails Breezy and ReactNative! 🎉", :green
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import {combineReducers, createStore, applyMiddleware} from 'redux'
|
3
|
+
import thunk from 'redux-thunk'
|
4
|
+
import { Provider } from 'react-redux'
|
5
|
+
import Breezy, {
|
6
|
+
rootReducer,
|
7
|
+
remote,
|
8
|
+
pageToInitialState,
|
9
|
+
} from '@jho406/breezy'
|
10
|
+
import {visit} from '@jho406/breezy/dist/action_creators'
|
11
|
+
import { StackNavigator } from 'react-navigation'
|
12
|
+
|
13
|
+
//Change the below when you have your first screen
|
14
|
+
const baseUrl = 'http://localhost:3000'
|
15
|
+
const initialPath = '/example'
|
16
|
+
const initialPage = {
|
17
|
+
data: {},
|
18
|
+
screen: 'ExampleScreen'
|
19
|
+
}
|
20
|
+
|
21
|
+
// Remove me when you have your first screen
|
22
|
+
import {View, Text} from 'react-native'
|
23
|
+
class ExampleScreen extends React.Component {
|
24
|
+
render() {
|
25
|
+
return (
|
26
|
+
<View>
|
27
|
+
<Text>Looks like you're up and running!</Text>
|
28
|
+
<Text>Next create your rails routes and controllers as usual</Text>
|
29
|
+
<Text>Then run the view generators `rails g breezy:view Post index -t mobile`</Text>
|
30
|
+
<Text>When ready, remove this ExampleScreen from App.js</Text>
|
31
|
+
</View>
|
32
|
+
)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
// This mapping can be auto populate through
|
37
|
+
// Breezy generators, for example:
|
38
|
+
// Run `rails g breezy:view Post index --mobile`
|
39
|
+
const mapping = {
|
40
|
+
ExampleScreen, //Remove me when you have your first screen
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
const navMapping = Object.entries(mapping).reduce((memo, [key, value])=> {
|
45
|
+
return {[key]: {screen: value}}
|
46
|
+
}, {})
|
47
|
+
|
48
|
+
|
49
|
+
function start({url, baseUrl='', initialPage={}}) {
|
50
|
+
const store = createStore(
|
51
|
+
rootReducer,
|
52
|
+
pageToInitialState(url, initialPage),
|
53
|
+
applyMiddleware(thunk)
|
54
|
+
)
|
55
|
+
|
56
|
+
Breezy.connect(store)
|
57
|
+
store.dispatch({type: 'BREEZY_SET_BASE_URL', baseUrl})
|
58
|
+
|
59
|
+
// Uncomment below if you need to fetch on the initial screen
|
60
|
+
// store.dispatch(visit({url}))
|
61
|
+
|
62
|
+
const Nav = StackNavigator(navMapping, {
|
63
|
+
initialRouteName: initialPage.screen,
|
64
|
+
initialRouteParams: {url}
|
65
|
+
})
|
66
|
+
|
67
|
+
return class extends React.Component {
|
68
|
+
render() {
|
69
|
+
return <Provider store={store}>
|
70
|
+
<Nav url={url}/>
|
71
|
+
</Provider>
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
const App = start({
|
78
|
+
url: initialPath,
|
79
|
+
baseUrl,
|
80
|
+
initialPage
|
81
|
+
})
|
82
|
+
|
83
|
+
export default App
|
84
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"name": "myapp",
|
3
|
+
"version": "0.1.0",
|
4
|
+
"private": true,
|
5
|
+
"devDependencies": {
|
6
|
+
"jest-expo": "^22.0.0",
|
7
|
+
"react-native-scripts": "1.7.0",
|
8
|
+
"react-test-renderer": "16.0.0-beta.5"
|
9
|
+
},
|
10
|
+
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
|
11
|
+
"scripts": {
|
12
|
+
"start": "react-native-scripts start",
|
13
|
+
"eject": "react-native-scripts eject",
|
14
|
+
"android": "react-native-scripts android",
|
15
|
+
"ios": "react-native-scripts ios",
|
16
|
+
"test": "node node_modules/jest/bin/jest.js --watch"
|
17
|
+
},
|
18
|
+
"jest": {
|
19
|
+
"preset": "jest-expo"
|
20
|
+
},
|
21
|
+
"dependencies": {
|
22
|
+
"expo": "^22.0.2",
|
23
|
+
"react": "16.0.0-beta.5",
|
24
|
+
"react-native": "^0.49.5",
|
25
|
+
"react-navigation": "^1.0.0-beta.19",
|
26
|
+
"react-redux": "^5.0.6",
|
27
|
+
"redux": "^3.7.2",
|
28
|
+
"redux-thunk": "^2.2.0"
|
29
|
+
"@jho406/breezy": "^0.2.3"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
import {combineReducers, createStore, applyMiddleware} from 'redux'
|
3
|
+
import thunk from 'redux-thunk'
|
4
|
+
import { Provider } from 'react-redux'
|
5
|
+
import { render } from 'react-dom'
|
6
|
+
import createHistory from 'history/createBrowserHistory'
|
7
|
+
import Breezy, {
|
8
|
+
rootReducer,
|
9
|
+
pageToInitialState,
|
10
|
+
setDOMListenersForNav,
|
11
|
+
setWindow,
|
12
|
+
argsForHistory,
|
13
|
+
argsForNavInitialState
|
14
|
+
} from '@jho406/breezy'
|
15
|
+
//The navigator is pretty bare bones
|
16
|
+
//Feel free to replace the implementation
|
17
|
+
import {Nav} from '@jho406/breezy/dist/utils/react'
|
18
|
+
|
19
|
+
|
20
|
+
// This mapping can be auto populate through
|
21
|
+
// Breezy generators, for example:
|
22
|
+
// Run `rails g breezy:view Post index`
|
23
|
+
const mapping = {
|
24
|
+
}
|
25
|
+
|
26
|
+
function start({window, url, baseUrl='', history, initialPage={}}) {
|
27
|
+
setWindow(window)
|
28
|
+
|
29
|
+
history.replace(...argsForHistory(url, initialPage))
|
30
|
+
|
31
|
+
const store = createStore(
|
32
|
+
rootReducer,
|
33
|
+
pageToInitialState(url, initialPage),
|
34
|
+
applyMiddleware(thunk)
|
35
|
+
)
|
36
|
+
|
37
|
+
Breezy.connect(store)
|
38
|
+
store.dispatch({type: 'BREEZY_SET_BASE_URL', baseUrl: baseUrl})
|
39
|
+
|
40
|
+
return class extends React.Component {
|
41
|
+
render() {
|
42
|
+
return <Provider store={store}>
|
43
|
+
<Nav ref={setDOMListenersForNav}
|
44
|
+
mapping={this.props.mapping}
|
45
|
+
initialState={argsForNavInitialState(url, initialPage)}
|
46
|
+
history={history}
|
47
|
+
/>
|
48
|
+
</Provider>
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
const App = start({
|
54
|
+
window: window,
|
55
|
+
url: window.location.href,
|
56
|
+
initialPage: window.BREEZY_INITIAL_PAGE_STATE,
|
57
|
+
history: createHistory({})
|
58
|
+
})
|
59
|
+
|
60
|
+
document.addEventListener("DOMContentLoaded", function() {
|
61
|
+
render(<App mapping={mapping}/>, document.getElementById('app'))
|
62
|
+
})
|
data/lib/install/web.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require "webpacker/configuration"
|
2
|
+
|
3
|
+
babelrc = Rails.root.join(".babelrc")
|
4
|
+
|
5
|
+
def append_js_tags
|
6
|
+
app_html = 'app/views/layouts/application.html.erb'
|
7
|
+
js_tag = <<-JS_TAG
|
8
|
+
|
9
|
+
<script type="text/javascript">
|
10
|
+
window.BREEZY_INITIAL_PAGE_STATE=<%= breezy_snippet %>;
|
11
|
+
</script>
|
12
|
+
JS_TAG
|
13
|
+
|
14
|
+
inject_into_file app_html, after: '<head>' do
|
15
|
+
js_tag
|
16
|
+
end
|
17
|
+
|
18
|
+
inject_into_file app_html, after: '<body>' do
|
19
|
+
"\n <div id='app'></div>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
if File.exist?(babelrc)
|
25
|
+
react_babelrc = JSON.parse(File.read(babelrc))
|
26
|
+
react_babelrc["presets"] ||= []
|
27
|
+
react_babelrc["plugins"] ||= []
|
28
|
+
|
29
|
+
if !react_babelrc["presets"].include?("react")
|
30
|
+
react_babelrc["presets"].push("react")
|
31
|
+
say "Copying react preset to your .babelrc file"
|
32
|
+
|
33
|
+
File.open(babelrc, "w") do |f|
|
34
|
+
f.puts JSON.pretty_generate(react_babelrc)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if !react_babelrc["plugins"].any?{|plugin| Array(plugin).include?("module-resolver")}
|
39
|
+
react_babelrc["plugins"].push(["module-resolver", {
|
40
|
+
"root": ["./app"],
|
41
|
+
"alias": {
|
42
|
+
"views": "./app/views",
|
43
|
+
"components": "./app/components",
|
44
|
+
"javascripts": "./app/javascripts"
|
45
|
+
}
|
46
|
+
}])
|
47
|
+
|
48
|
+
say "Copying module-resolver preset to your .babelrc file"
|
49
|
+
|
50
|
+
File.open(babelrc, "w") do |f|
|
51
|
+
f.puts JSON.pretty_generate(react_babelrc)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
else
|
56
|
+
say "Copying .babelrc to app root directory"
|
57
|
+
copy_file "#{__dir__}/templates/web/.babelrc", ".babelrc"
|
58
|
+
end
|
59
|
+
|
60
|
+
say "Copying application.js file to #{Webpacker.config.source_entry_path}"
|
61
|
+
copy_file "#{__dir__}/templates/web/application.js", "#{Webpacker.config.source_entry_path}/application.js"
|
62
|
+
|
63
|
+
say "Appending js tags to your application.html.erb"
|
64
|
+
append_js_tags
|
65
|
+
|
66
|
+
say "Installing all breezy dependencies"
|
67
|
+
run "yarn add history react react-dom babel-preset-react prop-types --save"
|
68
|
+
run "yarn add babel-plugin-module-resolver --save-dev"
|
69
|
+
run "yarn add react-redux redux --save-dev"
|
70
|
+
run "yarn add @jho406/breezy"
|
71
|
+
|
72
|
+
say "Webpacker now supports breezy.js 🎉", :green
|