nali 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/README.md +19 -14
  2. data/lib/client/javascripts/nali/application.js.coffee +59 -0
  3. data/lib/client/javascripts/nali/collection.js.coffee +188 -0
  4. data/lib/{assets → client}/javascripts/nali/connection.js.coffee +32 -32
  5. data/lib/{assets → client}/javascripts/nali/controller.js.coffee +28 -30
  6. data/lib/{assets → client}/javascripts/nali/cookie.js.coffee +5 -5
  7. data/lib/client/javascripts/nali/deferred.js.coffee +16 -0
  8. data/lib/client/javascripts/nali/extensions.js.coffee +18 -0
  9. data/lib/{assets → client}/javascripts/nali/index.js +2 -1
  10. data/lib/{assets → client}/javascripts/nali/jbone.min.js +1 -1
  11. data/lib/{assets → client}/javascripts/nali/model.js.coffee +208 -118
  12. data/lib/{assets → client}/javascripts/nali/nali.js.coffee +32 -32
  13. data/lib/client/javascripts/nali/notice.js.coffee +29 -0
  14. data/lib/{assets → client}/javascripts/nali/router.js.coffee +20 -22
  15. data/lib/{assets → client}/javascripts/nali/view.js.coffee +63 -60
  16. data/lib/generator/Gemfile +8 -8
  17. data/lib/generator/app/{assets → client}/javascripts/application.js.coffee +1 -1
  18. data/lib/generator/app/{assets → client}/javascripts/controllers/homes.js.coffee +4 -4
  19. data/lib/generator/app/client/javascripts/models/home.js.coffee +5 -0
  20. data/lib/generator/app/client/javascripts/views/home/index.js.coffee +9 -0
  21. data/lib/generator/app/{assets → client}/stylesheets/application.css.sass +1 -1
  22. data/lib/generator/app/{assets → client}/stylesheets/home/index.css.sass +5 -5
  23. data/lib/generator/app/{assets → client}/stylesheets/notices/error.css.sass +1 -1
  24. data/lib/generator/app/{assets → client}/stylesheets/notices/info.css.sass +1 -1
  25. data/lib/generator/app/{assets → client}/stylesheets/notices/warning.css.sass +1 -1
  26. data/lib/generator/app/{templates → client/templates}/application.html.erb +1 -1
  27. data/lib/generator/app/{templates → client/templates}/home/index.html +1 -1
  28. data/lib/generator/app/client/templates/notice/error.html +1 -0
  29. data/lib/generator/app/client/templates/notice/info.html +1 -0
  30. data/lib/generator/app/client/templates/notice/warning.html +1 -0
  31. data/lib/generator/app/server/clients.rb +15 -0
  32. data/lib/generator/app/{controllers → server/controllers}/application_controller.rb +2 -2
  33. data/lib/generator/app/{models → server/models}/access.yml +0 -0
  34. data/lib/generator/{config → app/server}/routes.rb +3 -3
  35. data/lib/generator/config/environments/development.rb +2 -2
  36. data/lib/generator/config/environments/production.rb +4 -4
  37. data/lib/generator/config/environments/test.rb +5 -5
  38. data/lib/nali/application.rb +24 -23
  39. data/lib/nali/connection.rb +14 -31
  40. data/lib/nali/controller.rb +36 -16
  41. data/lib/nali/generator.rb +38 -23
  42. data/lib/nali/helpers.rb +3 -3
  43. data/lib/nali/model.rb +36 -22
  44. data/lib/nali/tasks.rb +16 -25
  45. data/lib/nali/version.rb +2 -2
  46. metadata +85 -86
  47. data/lib/assets/javascripts/nali/application.js.coffee +0 -28
  48. data/lib/assets/javascripts/nali/collection.js.coffee +0 -150
  49. data/lib/assets/javascripts/nali/extensions.js.coffee +0 -19
  50. data/lib/assets/javascripts/nali/notice.js.coffee +0 -14
  51. data/lib/generator/app/assets/javascripts/models/home.js.coffee +0 -3
  52. data/lib/generator/app/assets/javascripts/views/home/index.js.coffee +0 -1
  53. data/lib/generator/app/templates/notice/error.html +0 -1
  54. data/lib/generator/app/templates/notice/info.html +0 -1
  55. data/lib/generator/app/templates/notice/warning.html +0 -1
  56. data/lib/generator/config/clients.rb +0 -19
  57. data/lib/generator/config/environments/development.rb~ +0 -32
  58. data/lib/generator/config/environments/production.rb~ +0 -80
@@ -2,11 +2,11 @@ source 'https://rubygems.org'
2
2
 
3
3
  gem 'nali'
4
4
 
5
- group :development, :test do
6
- gem 'debugger'
7
- gem 'sqlite3'
8
- end
9
-
10
- group :production do
11
- gem 'uglifier'
12
- end
5
+ # Use sqlite3 as the database for Active Record
6
+ gem 'sqlite3'
7
+
8
+ # Use Uglifier as compressor for JavaScript client
9
+ gem 'uglifier'
10
+
11
+ # Use debugger
12
+ #gem 'debugger'
@@ -1,4 +1,4 @@
1
1
  #= require nali
2
2
  #= require_tree .
3
3
 
4
- Nali.Application.run()
4
+ Nali.Application.run()
@@ -1,6 +1,6 @@
1
1
  Nali.Controller.extend Homes:
2
-
3
- actions:
2
+
3
+ actions:
4
4
  default: 'index'
5
-
6
- index: ->
5
+
6
+ index: ->
@@ -0,0 +1,5 @@
1
+ Nali.Model.extend Home:
2
+
3
+ attributes: {}
4
+
5
+ forced: true
@@ -0,0 +1,9 @@
1
+ Nali.View.extend HomeIndex:
2
+
3
+ events: []
4
+
5
+ helpers: {}
6
+
7
+ onShow: ->
8
+
9
+ onHide: ->
@@ -4,4 +4,4 @@
4
4
  */
5
5
 
6
6
  body
7
- margin: 0
7
+ margin: 0
@@ -4,15 +4,15 @@
4
4
  height: 100vh
5
5
  display: table-cell
6
6
  vertical-align: middle
7
- font-family: Lucida Grande, Arial, tahoma, verdana, sans-serif
8
-
7
+ font-family: Lucida Grande, Arial, tahoma, verdana, sans-serif
8
+
9
9
  .welcome, .title
10
10
  text-align: center
11
-
11
+
12
12
  .welcome
13
13
  font-size: 10vmin
14
14
  color: #ECF0F1
15
-
15
+
16
16
  .title
17
17
  font-size: 3vmin
18
- color: #BDC3C7
18
+ color: #BDC3C7
@@ -8,4 +8,4 @@
8
8
  border-radius: 0.3rem
9
9
  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.7)
10
10
  color: #F75E4E
11
- padding: 1.3rem
11
+ padding: 1.3rem
@@ -8,4 +8,4 @@
8
8
  border-radius: 0.3rem
9
9
  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.7)
10
10
  color: #58EB96
11
- padding: 1.3rem
11
+ padding: 1.3rem
@@ -8,4 +8,4 @@
8
8
  border-radius: 0.3rem
9
9
  box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.7)
10
10
  color: #FED93A
11
- padding: 1.3rem
11
+ padding: 1.3rem
@@ -8,4 +8,4 @@
8
8
  </head>
9
9
  <body>
10
10
  </body>
11
- </html>
11
+ </html>
@@ -1,2 +1,2 @@
1
1
  <div class="welcome">Welcome to Nali</div>
2
- <div class="title">Framework for developing async web applications</div>
2
+ <div class="title">Framework for developing async web applications</div>
@@ -0,0 +1,15 @@
1
+ module Nali::Clients
2
+
3
+ def client_connected( client )
4
+
5
+ end
6
+
7
+ def on_message( client, message )
8
+
9
+ end
10
+
11
+ def client_disconnected( client )
12
+
13
+ end
14
+
15
+ end
@@ -1,3 +1,3 @@
1
1
  class ApplicationController
2
-
3
- end
2
+
3
+ end
@@ -1,7 +1,7 @@
1
1
  Nali::Application.configure do |routes|
2
-
2
+
3
3
  # routes.get '/test' do
4
4
  # Your code
5
5
  # end
6
-
7
- end
6
+
7
+ end
@@ -1,7 +1,7 @@
1
1
  Nali::Application.configure :development do |config|
2
2
 
3
- config.assets_debug = true
3
+ config.client_debug = true
4
4
 
5
5
  ActiveRecord::Base.logger = false #Logger.new STDOUT
6
6
 
7
- end
7
+ end
@@ -2,10 +2,10 @@ Nali::Application.configure :production do |config|
2
2
 
3
3
  ActiveRecord::Base.logger = false
4
4
 
5
- config.assets_digest = true
5
+ config.client_digest = true
6
6
 
7
- config.assets.js_compressor = :uglify
7
+ config.client.js_compressor = :uglify
8
8
 
9
- config.assets.css_compressor = :scss
9
+ config.client.css_compressor = :scss
10
10
 
11
- end
11
+ end
@@ -2,12 +2,12 @@ Nali::Application.configure :test do |config|
2
2
 
3
3
  # ActiveRecord::Base.logger = false
4
4
 
5
- # config.assets_digest = true
5
+ # config.client_digest = true
6
6
 
7
- # config.assets_debug = true
7
+ # config.client_debug = true
8
8
 
9
- # config.assets.js_compressor = Uglifier.new( mangle: true )
9
+ # config.client.js_compressor = :uglify
10
10
 
11
- # config.assets.css_compressor = YUI::CssCompressor.new
11
+ # config.client.css_compressor = :scss
12
12
 
13
- end
13
+ end
@@ -4,9 +4,9 @@ module Nali
4
4
 
5
5
  set :root, File.expand_path( '.' )
6
6
  set :database_file, File.join( root, 'config/database.yml' )
7
- set :assets, Sprockets::Environment.new( root )
8
- set :assets_digest, false
9
- set :assets_debug, false
7
+ set :client, Sprockets::Environment.new( root )
8
+ set :client_digest, false
9
+ set :client_debug, false
10
10
  set :static, true
11
11
 
12
12
  register Sinatra::ActiveRecordExtension
@@ -20,39 +20,40 @@ module Nali
20
20
 
21
21
  configure do
22
22
 
23
- assets.cache = Sprockets::Cache::FileStore.new File.join( root, 'tmp/cache' )
23
+ client.cache = Sprockets::Cache::FileStore.new File.join( root, 'tmp/cache' )
24
24
 
25
- assets.append_path File.join( Nali.path, 'assets/javascripts' )
26
-
27
- %w( app/templates app/assets/stylesheets app/assets/javascripts lib/assets/stylesheets
28
- lib/assets/javascripts vendor/assets/stylesheets vendor/assets/javascripts
29
- ).each { |path| assets.append_path File.join( root, path ) }
25
+ client.append_path File.join( Nali.path, 'client/javascripts' )
26
+
27
+ %w( app/client/templates app/client/stylesheets app/client/javascripts lib/client/stylesheets
28
+ lib/client/javascripts vendor/client/stylesheets vendor/client/javascripts
29
+ ).each { |path| client.append_path File.join( root, path ) }
30
30
 
31
31
  Sprockets::Helpers.configure do |config|
32
- config.environment = assets
33
- config.debug = assets_debug
34
- config.digest = assets_digest
32
+ config.environment = client
33
+ config.debug = client_debug
34
+ config.digest = client_digest
35
+ config.prefix = '/client'
35
36
  end
36
37
 
37
38
  end
38
39
 
39
- get '/assets/*.*' do |path, ext|
40
- pass if ext == 'html' or not asset = settings.assets[ path + '.' + ext ]
40
+ get '/client/*.*' do |path, ext|
41
+ pass if ext == 'html' or not asset = settings.client[ path + '.' + ext ]
41
42
  content_type asset.content_type
42
43
  params[ :body ] ? asset.body : asset
43
44
  end
44
45
 
45
- require File.join( root, 'config/routes' )
46
+ require File.join( root, 'app/server/routes' )
46
47
 
47
48
  include Nali::Clients
48
49
 
49
50
  get '/*' do
50
51
  if !request.websocket?
51
- compiled_path = File.join settings.public_folder, 'assets/application.html'
52
+ compiled_path = File.join settings.public_folder, 'client/application.html'
52
53
  if settings.environment != :development and File.exists?( compiled_path )
53
54
  send_file compiled_path
54
55
  else
55
- settings.assets[ 'application.html' ]
56
+ settings.client[ 'application.html' ]
56
57
  end
57
58
  else
58
59
  request.websocket do |client|
@@ -65,18 +66,18 @@ module Nali
65
66
 
66
67
  def self.access_options
67
68
  if settings.environment == :development
68
- YAML.load_file( File.join( root, 'app/models/access.yml' ) ).keys_to_sym!
69
+ YAML.load_file( File.join( root, 'app/server/models/access.yml' ) ).keys_to_sym!
69
70
  else
70
- @access_options ||= YAML.load_file( File.join( root, 'app/models/access.yml' ) ).keys_to_sym!
71
+ @access_options ||= YAML.load_file( File.join( root, 'app/server/models/access.yml' ) ).keys_to_sym!
71
72
  end
72
73
  end
73
74
 
74
75
  def self.initialize!
75
76
  Dir[ File.join( root, 'lib/*/**/*.rb' ) ].each { |file| require( file ) }
76
- require File.join( root, 'app/controllers/application_controller.rb' )
77
- Dir[ File.join( root, 'app/**/*.rb' ) ].each { |file| require( file ) }
77
+ require File.join( root, 'app/server/controllers/application_controller.rb' )
78
+ Dir[ File.join( root, 'app/server/**/*.rb' ) ].each { |file| require( file ) }
78
79
  require File.join( root, 'config/application' )
79
- require File.join( root, 'config/clients' )
80
+ require File.join( root, 'app/server/clients' )
80
81
  Dir[ File.join( root, 'config/initializers/**/*.rb' ) ].each { |file| require( file ) }
81
82
  self
82
83
  end
@@ -91,4 +92,4 @@ module Nali
91
92
 
92
93
  end
93
94
 
94
- end
95
+ end
@@ -3,33 +3,10 @@ module EventMachine
3
3
  class Connection
4
4
 
5
5
  def reset
6
- @filters = {}
7
6
  @storage = {}
8
7
  @watches = {}
9
8
  end
10
-
11
- def filters( model_name )
12
- @filters ||= {}
13
- @filters[ model_name ] ||= []
14
- end
15
-
16
- def filters_add( model_name, new_filter )
17
- unless( new_filter.keys.include?( :id ) and new_filter.keys.length == 1 )
18
- exist = false
19
- filters( model_name ).each { |filter| exist = true if filter.sort.to_s == new_filter.sort.to_s }
20
- filters( model_name ) << new_filter unless exist
21
- end
22
- end
23
-
24
- def filter?( model )
25
- filters( model.class.name.to_sym ).each do |filter|
26
- result = true
27
- filter.each { |key, value| result = false if model[ key ] != value }
28
- return result if result
29
- end
30
- false
31
- end
32
-
9
+
33
10
  def []( name )
34
11
  @storage ||= {}
35
12
  @storage[ name ] or nil
@@ -47,6 +24,10 @@ module EventMachine
47
24
  def watch( model )
48
25
  watches[ model.class.name + model.id.to_s ] ||= 0
49
26
  end
27
+
28
+ def unwatch( model )
29
+ watches.delete model.class.name + model.id.to_s
30
+ end
50
31
 
51
32
  def watch?( model )
52
33
  if watches[ model.class.name + model.id.to_s ] then true else false end
@@ -64,12 +45,14 @@ module EventMachine
64
45
  send hash.to_json
65
46
  end
66
47
 
67
- def sync( model )
68
- params, relations = model.get_sync_params( self )
69
- if not params.empty? and ( watch_time( model ) < model.updated_at.to_f or model.destroyed? )
70
- watch_time_up model
71
- relations.each { |relation| sync relation }
72
- send_json action: :sync, params: params
48
+ def sync( *models )
49
+ models.flatten.compact.each do |model|
50
+ params, relations = model.get_sync_params( self )
51
+ if not params.empty? and ( watch_time( model ) < model.updated_at.to_f or model.destroyed? )
52
+ if model.destroyed? then unwatch( model ) else watch_time_up model end
53
+ relations.each { |relation| sync relation }
54
+ send_json action: :sync, params: params
55
+ end
73
56
  end
74
57
  end
75
58
 
@@ -99,4 +82,4 @@ module EventMachine
99
82
 
100
83
  end
101
84
  end
102
- end
85
+ end
@@ -2,19 +2,23 @@ module Nali
2
2
 
3
3
  module Controller
4
4
 
5
- attr_reader :client, :params, :message
5
+ attr_reader :client, :params
6
6
 
7
7
  def self.included( base )
8
8
  base.extend self
9
9
  base.class_eval do
10
- self.class_variable_set :@@befores, []
11
- self.class_variable_set :@@afters, []
10
+ self.class_variable_set :@@befores, []
11
+ self.class_variable_set :@@afters, []
12
+ self.class_variable_set :@@selectors, {}
12
13
  def self.befores
13
14
  self.class_variable_get :@@befores
14
15
  end
15
16
  def self.afters
16
17
  self.class_variable_get :@@afters
17
18
  end
19
+ def self.selectors
20
+ self.class_variable_get :@@selectors
21
+ end
18
22
  end
19
23
  end
20
24
 
@@ -29,7 +33,7 @@ module Nali
29
33
  end
30
34
 
31
35
  def save
32
- params[ :id ] ? update : create
36
+ params[ :id ].to_i.to_s == params[ :id ].to_s ? update : create
33
37
  end
34
38
 
35
39
  def create
@@ -38,7 +42,7 @@ module Nali
38
42
  permit_params options
39
43
  if ( model = model_class.new( params ) ).save
40
44
  trigger_success model.get_sync_params( client )[0]
41
- model.sync client
45
+ client.sync model
42
46
  else trigger_failure end
43
47
  end
44
48
  end
@@ -54,28 +58,22 @@ module Nali
54
58
  end
55
59
  end
56
60
  end
57
-
58
- def select
59
- model_class.where( params ).each { |model| client.sync model }
60
- client.filters_add model_name, params
61
- end
62
61
 
63
62
  def destroy
64
63
  if model = model_class.find_by_id( params[ :id ] )
65
64
  model.access_action( :destroy, client ) do |options|
66
65
  model.destroy()
67
- trigger_success model.id
68
- model.sync
66
+ trigger_success model.id
69
67
  end
70
68
  else trigger_failure end
71
69
  end
72
70
 
73
71
  def trigger_success( params = nil )
74
- client.send_json( { action: 'success', params: params, journal_id: message[ :journal_id ] } )
72
+ client.send_json( { action: 'success', params: params, journal_id: @message[ :journal_id ] } )
75
73
  end
76
74
 
77
75
  def trigger_failure( params = nil )
78
- client.send_json( { action: 'failure', params: params, journal_id: message[ :journal_id ] } )
76
+ client.send_json( { action: 'failure', params: params, journal_id: @message[ :journal_id ] } )
79
77
  end
80
78
 
81
79
  def before( &closure )
@@ -101,11 +99,33 @@ module Nali
101
99
  def after_except( *methods, &closure )
102
100
  register_after closure: closure, except: methods
103
101
  end
102
+
103
+ def selector( name, &closure )
104
+ selectors[ name ] = closure
105
+ end
104
106
 
105
- def runAction( name )
107
+ def select( name )
108
+ selected = nil
106
109
  self.runFilters name
107
- self.send( name ) unless @stopped
110
+ if !@stopped and selector = self.class.selectors[ name ]
111
+ selected = instance_eval( &selector )
112
+ end
108
113
  self.runFilters name, :after
114
+ if !@stopped and selected and ( selected.is_a?( ActiveRecord::Relation ) or selected.is_a?( ActiveRecord::Base ) )
115
+ client.sync selected
116
+ end
117
+ end
118
+
119
+ def runAction( name )
120
+ if name == :select
121
+ selector = params[ :selector ].to_sym
122
+ @params = params[ :params ]
123
+ self.select selector
124
+ else
125
+ self.runFilters name
126
+ self.send( name ) unless @stopped
127
+ self.runFilters name, :after
128
+ end
109
129
  end
110
130
 
111
131
  def stop