inesita 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Gemfile +7 -1
  5. data/LICENSE.md +21 -0
  6. data/README.md +5 -3
  7. data/Rakefile +17 -0
  8. data/inesita.gemspec +7 -5
  9. data/lib/inesita.rb +28 -1
  10. data/lib/inesita/app_files_listener.rb +42 -0
  11. data/lib/inesita/cli.rb +1 -0
  12. data/lib/inesita/cli/build.rb +33 -10
  13. data/lib/inesita/cli/new.rb +2 -5
  14. data/lib/inesita/cli/server.rb +1 -2
  15. data/lib/inesita/cli/template/Gemfile.tt +9 -6
  16. data/lib/inesita/cli/template/app/application.js.rb.tt +2 -4
  17. data/lib/inesita/cli/template/app/components/home.rb.tt +1 -1
  18. data/lib/inesita/cli/template/app/index.html.slim.tt +1 -9
  19. data/lib/inesita/cli/template/app/{components/layout.rb.tt → layout.rb.tt} +1 -1
  20. data/lib/inesita/cli/template/config.ru.tt +6 -1
  21. data/lib/inesita/cli/template/static/inesita-rb.png +0 -0
  22. data/lib/inesita/config.rb +8 -0
  23. data/lib/inesita/live_reload.rb +47 -0
  24. data/lib/inesita/minify.rb +34 -0
  25. data/lib/inesita/server.rb +56 -49
  26. data/lib/rubame.rb +156 -0
  27. data/opal/inesita.rb +12 -2
  28. data/opal/inesita/application.rb +37 -15
  29. data/opal/inesita/component.rb +37 -36
  30. data/opal/inesita/{component_withs.rb → component_properties.rb} +1 -1
  31. data/opal/inesita/component_virtual_dom_extension.rb +22 -0
  32. data/opal/inesita/error.rb +4 -0
  33. data/opal/inesita/layout.rb +1 -3
  34. data/opal/inesita/live_reload.rb +79 -0
  35. data/opal/inesita/router.rb +24 -20
  36. data/opal/inesita/routes.rb +16 -13
  37. data/opal/inesita/store.rb +6 -1
  38. data/spec/lib/nil_spec.rb +7 -0
  39. data/spec/lib/spec_helper.rb +1 -0
  40. data/spec/opal/application_spec.rb +48 -0
  41. data/spec/opal/component_spec.rb +56 -0
  42. data/spec/opal/layout_spec.rb +9 -0
  43. data/spec/opal/router_spec.rb +60 -0
  44. data/spec/opal/spec_helper.rb +5 -0
  45. data/spec/opal/store_spec.rb +17 -0
  46. metadata +69 -16
  47. data/TODO.md +0 -8
  48. data/opal/inesita/js_helpers.rb +0 -27
  49. data/test.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83190d831f12858fb0b8c2e4c2a5575dc3863c49
4
- data.tar.gz: b5a6b50b689ace6fbaf726a64ea5c4dd2979a53d
3
+ metadata.gz: e75bb45e13cde077690f59ac0196e2b630f9d40f
4
+ data.tar.gz: 16e95d9a8c923eff86a7d6f84800807cbc2dd0d7
5
5
  SHA512:
6
- metadata.gz: c4018bda515c29a290b83166a73a4405e60db9e58136a78fe7ea7c8c7e20600540da7d1823acad5470d41d28f1d46fcc6ef8264f1869a45e183d997df4abbbdd
7
- data.tar.gz: d6bcc46517b00b20712df8874821bfba1b3fe8be77fe2662461413663483da2d6011b81a19bef856bdd27b85bdbe1fbe4eb2ad47b7d1a297f26aa611b8709cff
6
+ metadata.gz: 935deea53673ada2f81a43202c1e75bfa86242f501ec9ee7241713b49a60479017a7dcf30eea5806a3d1b3fdf1255bc6bc58a18d3d56a4ccb0a6ae5323c8dc68
7
+ data.tar.gz: ab86e398eaa70c544249753da02e07ddaaabce585879343f163d7cb04b8119ab655c0974aa45a56b8a7dfc282e348bae70297e37897446a59610035883c2e228
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache:
4
+ bundler: true
5
+ rvm:
6
+ - 2.2.3
7
+ notifications:
8
+ webhooks:
9
+ urls: https://webhooks.gitter.im/e/04c689326f7cd8e4d499
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ ## 0.3.0 (edge)
2
+
3
+ * live-reload
4
+ * rename `update_dom` to `render!`
5
+ * include `opal-browser`
6
+ * `after_render` component method - executes after component is rendered
7
+ * add minification support
8
+ * specs added
9
+ * add static support - for serving images
data/Gemfile CHANGED
@@ -1,3 +1,9 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'bundler', '~> 1.3'
6
+ gem 'rspec', '~> 3.0'
7
+ gem 'opal-rspec', '~> 0.5.0'
8
+ gem 'rake', '~> 10.4'
9
+ gem 'opal-browser', '~> 0.2'
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Michał Kalbarczyk
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.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Inesita [![Gem Version](https://badge.fury.io/rb/inesita.svg)](http://badge.fury.io/rb/inesita) [![Code Climate](https://codeclimate.com/github/inesita-rb/inesita/badges/gpa.svg)](https://codeclimate.com/github/inesita-rb/inesita) [![Gem Dependencies](https://gemnasium.com/inesita-rb/inesita.png)](https://gemnasium.com/inesita-rb/inesita)
1
+ # Inesita [![Gem Version](https://badge.fury.io/rb/inesita.svg)](http://badge.fury.io/rb/inesita) [![Code Climate](https://codeclimate.com/github/inesita-rb/inesita/badges/gpa.svg)](https://codeclimate.com/github/inesita-rb/inesita) [![Dependency Status](https://gemnasium.com/inesita-rb/inesita.svg)](https://gemnasium.com/inesita-rb/inesita) [![Build Status](https://travis-ci.org/inesita-rb/inesita.svg?branch=master)](https://travis-ci.org/inesita-rb/inesita) [![Join the chat at https://gitter.im/inesita-rb/inesita](https://img.shields.io/badge/%E2%8A%AA%20GITTER%20-JOIN%20CHAT%20%E2%86%92-brightgreen.svg)](https://gitter.im/inesita-rb/inesita?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2
2
 
3
3
  Inesita is a web frontend framework for fast building browser application using Ruby. It uses Virtual DOM for page render.
4
4
 
@@ -8,5 +8,7 @@ More detailed description [here](https://inesita-rb.github.io).
8
8
 
9
9
  ## Examples
10
10
 
11
- - [Example application](https://github.com/inesita-rb/playground)
12
- - [TodoMVC application](https://github.com/inesita-rb/todomvc)
11
+ - [[DEMO](http://inesita-playground.netlify.com/)] [Example application source](https://github.com/inesita-rb/playground)
12
+ - [[DEMO](http://inesita-todomvc.netlify.com/)] [TodoMVC application source](https://github.com/inesita-rb/todomvc)
13
+ - [[DEMO](http://inesita-dbmonster.netlify.com/)] [DBMonster application source](https://github.com/inesita-rb/dbmonster)
14
+ - [[DEMO](https://inesita-asciify-me.netlify.com/)] [Asciify Me application source](https://github.com/inesita-rb/asciify-me)
data/Rakefile CHANGED
@@ -1,3 +1,20 @@
1
1
  require 'bundler'
2
2
  Bundler.require
3
3
  Bundler::GemHelper.install_tasks
4
+
5
+ require 'rspec/core/rake_task'
6
+ require 'opal/rspec/rake_task'
7
+ require 'opal/browser'
8
+
9
+ ENV['SPEC_OPTS'] = '--color'
10
+
11
+ RSpec::Core::RakeTask.new(:spec_lib) do |task|
12
+ task.pattern = 'spec/lib/**/*_spec.rb'
13
+ end
14
+
15
+ Opal::RSpec::RakeTask.new(:spec_opal) do |_server, task|
16
+ task.pattern = 'spec/opal/**/*_spec.rb'
17
+ task.default_path = 'spec/opal'
18
+ end
19
+
20
+ task default: [:spec_lib, :spec_opal]
data/inesita.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'inesita'
3
- s.version = '0.2.3'
4
- s.authors = [ 'Michał Kalbarczyk' ]
3
+ s.version = '0.3.0'
4
+ s.authors = ['Michał Kalbarczyk']
5
5
  s.email = 'fazibear@gmail.com'
6
6
  s.homepage = 'http://github.com/inesita-rb/inesita'
7
7
  s.summary = 'Frontend web framework for Opal'
@@ -12,11 +12,13 @@ Gem::Specification.new do |s|
12
12
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
13
  s.require_paths = ['lib']
14
14
 
15
- s.add_dependency 'opal', '~> 0.8'
16
- s.add_dependency 'opal-virtual-dom', '~> 0.1.0'
15
+ s.add_dependency 'opal', '~> 0.9'
16
+ s.add_dependency 'opal-browser', '~> 0.2'
17
+ s.add_dependency 'opal-virtual-dom', '~> 0.3.0'
17
18
  s.add_dependency 'slim', '~> 3.0'
18
19
  s.add_dependency 'sass', '~> 3.4'
19
20
  s.add_dependency 'thor', '~> 0.19'
20
21
  s.add_dependency 'rack-rewrite', '~> 1.5'
21
- s.add_development_dependency 'rake', '~> 10.4'
22
+ s.add_dependency 'listen', '~> 3.0'
23
+ s.add_dependency 'websocket', '~> 1.0'
22
24
  end
data/lib/inesita.rb CHANGED
@@ -1,9 +1,36 @@
1
1
  require 'opal'
2
2
  Opal.append_path File.expand_path('../../opal', __FILE__)
3
- Opal.use_gem 'opal-virtual-dom'
4
3
 
5
4
  require 'opal-virtual-dom'
5
+ require 'opal-browser'
6
6
  require 'slim'
7
7
  require 'sass'
8
8
 
9
+ require 'singleton'
10
+ require 'listen'
11
+ require 'rubame'
12
+
13
+ require 'inesita/config'
14
+ require 'inesita/app_files_listener'
15
+ require 'inesita/live_reload'
9
16
  require 'inesita/server'
17
+
18
+ module Inesita
19
+ module_function
20
+
21
+ def env
22
+ @env || :development
23
+ end
24
+
25
+ def env=(env)
26
+ @env = env
27
+ end
28
+
29
+ def assets_code
30
+ @assets_code
31
+ end
32
+
33
+ def assets_code=(code)
34
+ @assets_code = code
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ module Inesita
2
+ class AppFilesListener
3
+ include Singleton
4
+ CURRENT_DIR = Dir.pwd
5
+
6
+ def initialize
7
+ @websockets = []
8
+ listener = Listen.to(Config::APP_DIR) do |modified, added, _removed|
9
+ (modified + added).each do |file|
10
+ @websockets.each do |ws|
11
+ ws.send transform_filename(file)
12
+ end
13
+ end
14
+ end
15
+ listener.start
16
+ end
17
+
18
+ def add_ws(ws)
19
+ @websockets << ws
20
+ end
21
+
22
+ def rm_ws(ws)
23
+ @websockets.delete(ws)
24
+ end
25
+
26
+ def transform_filename(filename)
27
+ filename.sub!(CURRENT_DIR, '')
28
+ path = filename.split('/')
29
+ path.delete('')
30
+ path.delete(Config::APP_DIR)
31
+ path = path.join('/').split('.')
32
+
33
+ prefix = Config::ASSETS_PREFIX
34
+ name = path.first
35
+ if path.include?('rb') || path.include?('js')
36
+ "#{prefix}|#{name}|js"
37
+ elsif path.include?('sass') || path.include?('css')
38
+ "#{prefix}|stylesheet|css"
39
+ end
40
+ end
41
+ end
42
+ end
data/lib/inesita/cli.rb CHANGED
@@ -11,6 +11,7 @@ rescue Bundler::GemfileNotFound
11
11
  end
12
12
 
13
13
  require 'rack'
14
+ require 'inesita/minify'
14
15
  require 'inesita/cli/build'
15
16
  require 'inesita/cli/server'
16
17
  require 'inesita/cli/new'
@@ -5,7 +5,7 @@ class InesitaCLI < Thor
5
5
 
6
6
  namespace :build
7
7
 
8
- desc "build [OPTIONS]", "Build Inesita app"
8
+ desc 'build [OPTIONS]', 'Build Inesita app'
9
9
 
10
10
  method_option :force,
11
11
  aliases: ['-f'],
@@ -18,18 +18,41 @@ class InesitaCLI < Thor
18
18
  desc: 'build destination directory'
19
19
 
20
20
  def build
21
+ Inesita.env = :production
22
+ assets = Inesita::Server.new.assets_app
23
+
21
24
  build_dir = options[:destination]
25
+ force = options[:force]
22
26
 
23
- assets = Inesita::Server.assets
24
- Inesita::Server.set_global_vars(assets, false)
27
+ empty_directory build_dir, force: force
25
28
 
26
- index = assets['index.html']
27
- javascript = assets['application.js']
28
- stylesheet = assets['stylesheet.css']
29
+ copy_static(build_dir, force)
30
+ create_index(build_dir, assets['index.html'].source, force)
31
+ create_js(build_dir, assets['application.js'].source, force)
32
+ create_css(build_dir, assets['stylesheet.css'].source, force)
33
+ end
29
34
 
30
- empty_directory build_dir, force: options[:force]
31
- create_file File.join(build_dir, 'index.html'), index.source, force: options[:force]
32
- create_file File.join(build_dir, 'application.js'), javascript.source, force: options[:force]
33
- create_file File.join(build_dir, 'stylesheet.css'), stylesheet.source, force: options[:force]
35
+ no_commands do
36
+ def copy_static(build_dir, force)
37
+ Dir.glob('./static/**/*').each do |file|
38
+ if File.directory?(file)
39
+ empty_directory File.join(build_dir, file), force: force
40
+ else
41
+ copy_file File.absolute_path(file), File.join(build_dir, file), force: force
42
+ end
43
+ end
44
+ end
45
+
46
+ def create_index(build_dir, html, force)
47
+ create_file File.join(build_dir, 'index.html'), Inesita::Minify.html(html), force: force
48
+ end
49
+
50
+ def create_js(build_dir, javascript, force)
51
+ create_file File.join(build_dir, 'application.js'), Inesita::Minify.js(javascript), force: force
52
+ end
53
+
54
+ def create_css(build_dir, stylesheet, force)
55
+ create_file File.join(build_dir, 'stylesheet.css'), Inesita::Minify.css(stylesheet), force: force
56
+ end
34
57
  end
35
58
  end
@@ -5,7 +5,7 @@ class InesitaCLI < Thor
5
5
 
6
6
  namespace :new
7
7
 
8
- desc "new PROJECT_NAME", "Create Inesita app"
8
+ desc 'new PROJECT_NAME', 'Create Inesita app'
9
9
 
10
10
  method_option :force,
11
11
  aliases: ['-f'],
@@ -13,10 +13,7 @@ class InesitaCLI < Thor
13
13
  desc: 'force overwrite'
14
14
 
15
15
  def new(project_dir)
16
- puts 'x'
17
- directory('template', project_dir, {
18
- project_name: project_dir
19
- })
16
+ directory('template', project_dir, project_name: project_dir)
20
17
 
21
18
  inside project_dir do
22
19
  run 'bundle install'
@@ -1,10 +1,9 @@
1
1
  class InesitaCLI < Thor
2
-
3
2
  check_unknown_options!
4
3
 
5
4
  namespace :server
6
5
 
7
- desc "server [OPTIONS]", "Starts Inesita server"
6
+ desc 'server [OPTIONS]', 'Starts Inesita server'
8
7
  method_option :port,
9
8
  aliases: '-p',
10
9
  default: 9292,
@@ -1,9 +1,12 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem 'opal-browser', '~> 0.2'
4
- gem 'inesita', '~> 0.2.0'
3
+ # inesita gem
4
+ gem 'inesita', '~> 0.3.0'
5
5
 
6
- source 'https://rails-assets.org' do
7
- gem 'rails-assets-bootstrap'
8
- gem 'rails-assets-virtual-dom'
9
- end
6
+ # add this gems to minify files on build
7
+ #
8
+ # gem 'uglifier'
9
+ # gem 'htmlcompressor'
10
+
11
+ # bootsrap assets
12
+ gem 'bootstrap-sass'
@@ -1,11 +1,9 @@
1
- require 'virtual-dom'
2
- require 'opal'
3
- require 'browser'
4
- require 'browser/interval'
5
1
  require 'inesita'
6
2
 
7
3
  require 'router'
8
4
  require 'store'
5
+ require 'layout'
6
+
9
7
  require_tree './components'
10
8
 
11
9
  $document.ready do
@@ -3,7 +3,7 @@ class Home
3
3
 
4
4
  def render
5
5
  div class: 'jumbotron text-center' do
6
- img src: 'http://avatars.githubusercontent.com/inesita-rb'
6
+ img src: '/static/inesita-rb.jpg'
7
7
  h1 do
8
8
  text "Hello I'm Inesita"
9
9
  end
@@ -2,13 +2,5 @@ doctype html
2
2
  html
3
3
  head
4
4
  title <%= config[:project_name] %>
5
- - if $DEVELOPMENT_MODE
6
- link href=asset_path('stylesheet.css') rel='stylesheet' type='text/css'
7
- - $SCRIPT_FILES.each do |file|
8
- script src=asset_path(file)
9
- - else
10
- link href='stylesheet.css' rel='stylesheet' type='text/css'
11
- script src='application.js'
12
- javascript:
13
- #{{$LOAD_ASSETS_CODE}}
5
+ == Inesita.assets_code
14
6
  body
@@ -4,7 +4,7 @@ class Layout
4
4
  def render
5
5
  div class: 'container' do
6
6
  component NavBar
7
- component outlet
7
+ component router
8
8
  end
9
9
  end
10
10
  end
@@ -1,4 +1,9 @@
1
+ # initialize bundler
1
2
  require 'bundler'
2
3
  Bundler.require
3
4
 
4
- run Inesita::Server.create
5
+ # you can comment this line to disable live-reload
6
+ use Inesita::LiveReload
7
+
8
+ # run inesita server
9
+ run Inesita::Server.new
@@ -0,0 +1,8 @@
1
+ module Inesita
2
+ module Config
3
+ SOURCE_MAP_PREFIX = '/__OPAL_MAPS__'
4
+ ASSETS_PREFIX = '/__ASSETS__'
5
+ APP_DIR = 'app'
6
+ STATIC_DIR = '/static'
7
+ end
8
+ end
@@ -0,0 +1,47 @@
1
+ require 'rubame'
2
+
3
+ module Inesita
4
+ class LiveReload
5
+ INJECT_CODE = Opal.compile(File.read(File.expand_path('../../../opal/inesita/live_reload.rb', __FILE__)))
6
+
7
+ def initialize(app, _options = {})
8
+ @app = app
9
+ Thread.new do
10
+ begin
11
+ init_live_reload
12
+ rescue => e
13
+ puts e
14
+ end
15
+ end
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, body = @app.call(env)
20
+ if status == 200
21
+ new_body = inject_script(body)
22
+ headers['Content-Length'] = new_body.bytesize.to_s
23
+ [status, headers, [new_body]]
24
+ else
25
+ [status, headers, body]
26
+ end
27
+ end
28
+
29
+ def inject_script(body)
30
+ new_body = ''
31
+ body.each { |line| new_body += line.to_s }
32
+ new_body.gsub('{ Opal.loaded', "{ #{INJECT_CODE} Opal.loaded")
33
+ end
34
+
35
+ def init_live_reload
36
+ AppFilesListener.instance
37
+ server = Rubame::Server.new('0.0.0.0', 23654)
38
+ loop do
39
+ server.run do |ws|
40
+ ws.onopen { AppFilesListener.instance.add_ws(ws) }
41
+ ws.onclose { AppFilesListener.instance.rm_ws(ws) }
42
+ ws.onmessage { |msg| ws.send 'pong' if msg == 'ping' }
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end