nali 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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