roda-component 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e07b2592555f0305b5ff63e7b1a5d0cdc595f337
4
- data.tar.gz: a9292504e6a90f5aec922f3908a8abed452cbb23
3
+ metadata.gz: 7a0aee4b44c06ddda8a7f16cadc0ab4f36cb8bdf
4
+ data.tar.gz: 3b43bcaccdcd4946f8e4cabcfabb9eae516c5d88
5
5
  SHA512:
6
- metadata.gz: 7e3c511932310c7c1958b248944bd61b3507ce506191d4ced846618cc54a25b64ba955b1bd1c1cf83fbd140f3ac6d2f576f04b1e76f1a22b970532936e43cd70
7
- data.tar.gz: 06c976af76747799ba76fe4661a21a00fa927a7614a8c4d7811f4261037ed53d31c05bab95a131a8da24f90861a2888557285c203e8675d86ff9dd096d06174c
6
+ metadata.gz: dd9fad6927044e7d4bf367ee524c68c4c600c93a3e93a26af8d5996d0669b7edecdf4d91f6c28ee47ba93b2160b8d63e7f9fc2eafb7d02ced7bd4e7b341a087f
7
+ data.tar.gz: e7c055e597beccfd745f60a08b8cd56947e2d5613aa93d97427e2f033cd9fb95aef33a6b4aaa9c7e6ec6b39d886fa991065d207475fe982dcca64b6b127f5db5
@@ -6,32 +6,79 @@ if RUBY_ENGINE == 'opal'
6
6
  class Faye
7
7
  include Native
8
8
 
9
- def initialize url
10
- super `new Faye.Client(#{url})`
11
- end
12
-
13
9
  alias_native :subscribe
10
+ alias_native :unsubscribe
14
11
  alias_native :publish
12
+ alias_native :bind
13
+ alias_native :cancel
14
+ alias_native :on
15
+ alias_native :then
15
16
  alias_native :set_header, :setHeader
16
17
  alias_native :add_extension, :addExtension
18
+
19
+ def initialize url
20
+ super `new Faye.Client(#{url})`
21
+ set_header 'X-CSRF-TOKEN', Element.find('meta[name=_csrf]').attr('content')
22
+ add_extension({
23
+ incoming: ->(message, block) { incoming message, block },
24
+ outgoing: ->(message, block) { outgoing message, block }
25
+ })
26
+ end
27
+
28
+ def public_id
29
+ @public_id ||= generate_id
30
+ end
31
+
32
+ def private_id
33
+ @private_id ||= generate_id
34
+ end
35
+
36
+ def incoming message, block
37
+ msg = Native(message)
38
+
39
+ if (!@public_id && !@private_id) && msg[:channel] == '/meta/handshake'
40
+ subscribe "/components/incoming/#{private_id}/#{public_id}" do |data|
41
+ data = Native(data)
42
+ event_id = data[:event_id]
43
+ body = Element['body']
44
+
45
+ body.trigger(event_id, data[:local], data)
46
+ body.off event_id
47
+ end
48
+ end
49
+
50
+ block.call message
51
+ end
52
+
53
+ def outgoing message, block
54
+ message = %x{
55
+ message = #{message}
56
+ message.ext = message.ext || {};
57
+ message.ext.csrfToken = $('meta[name=_csrf]').attr('content');
58
+ }
59
+ block.call message
60
+ end
61
+
62
+ private
63
+
64
+ def generate_id
65
+ o = [('a'..'z'), ('A'..'Z'), (0..9)].map { |i| i.to_a }.flatten
66
+ (0...50).map { o[rand(o.length)] }.join
67
+ end
17
68
  end
18
69
  end
19
70
  end
20
71
  else
72
+ require 'faye'
73
+ require 'roda/component/ohm'
74
+ require 'roda/component/models/user'
75
+ require 'roda/component/models/channel'
76
+
21
77
  class Roda
22
78
  class Component
23
79
  class Faye
24
80
  class CsrfProtection
25
- def incoming(m, request, callback)
26
- # # fix due to opal and wrapping message in native like Native(message)
27
- message = { '_id' => m['_id']}
28
- message.merge! m['native']
29
-
30
- ap '======================'
31
- ap message
32
- ap request.session
33
- ap '======================'
34
-
81
+ def incoming(message, request, callback)
35
82
  session_token = request.session['csrf.token']
36
83
  message_token = message['ext'] && message['ext'].delete('csrfToken')
37
84
 
@@ -41,19 +88,47 @@ else
41
88
 
42
89
  callback.call(message)
43
90
  end
91
+ end
92
+
93
+ class ChannelManager
94
+ def incoming(message, request, callback)
95
+ app = get_app(request)
96
+
97
+ if data = message['data']
98
+ case data['type']
99
+ when 'event'
100
+ options = { local: data['local'] }
101
+ data['event_type'] == 'call' \
102
+ ? options[:call] = data['event_method'] \
103
+ : options[:trigger] = data['event_method']
104
+
105
+ message['data']['local'] = app.roda_component(:"#{data['name']}", options)
106
+ message['channel'] = message['channel'].gsub(/outgoing/, 'incoming')
107
+ end
108
+ end
109
+
110
+ callback.call message
111
+ end
112
+
113
+ # /components/:id/:comp/:action
114
+ # def outgoing(message, request, callback)
115
+ # app = get_app request
44
116
  #
45
- # def outgoing(m, request, callback)
46
- # ap '======================'
47
- # ap 'outgoing'
48
- # ap m
49
- # ap request.session
50
- # ap '======================'
51
- # #
52
- # # unless session_token == message_token
53
- # # message['error'] = '401::Access denied'
54
- # # end
55
- # callback.call(m)
117
+ # # message[:data] = app.roda_component(:auth, call: :cow) || false
118
+ #
119
+ # ap '====OUTGOING===='
120
+ # ap message
121
+ # ap '================'
122
+ #
123
+ # callback.call message
56
124
  # end
125
+
126
+ def get_app request
127
+ request.env['RODA_COMPONENT_FROM_FAYE'] = true
128
+ a = Class.new(Roda::Component.app.class).new
129
+ a.instance_variable_set(:@_request, request)
130
+ a
131
+ end
57
132
  end
58
133
  end
59
134
  end
@@ -10,11 +10,11 @@ class Roda
10
10
 
11
11
  # this is a hack because it seems like display is a ruby object method
12
12
  # when doing method(:display) it gives #<Method: # Roda::Component::Instance(Kernel)#display>
13
- def display *args
14
- method_missing(*args)
13
+ def display *args, &block
14
+ method_missing('display', *args, &block)
15
15
  end
16
16
 
17
- def method_missing method = 'display', *args, &block
17
+ def method_missing method, *args, &block
18
18
  if instance.respond_to? method, true
19
19
  instance.send method, *args, &block
20
20
  elsif server && scope && scope.respond_to?(method, true)
@@ -0,0 +1,11 @@
1
+ class Roda
2
+ class Component
3
+ module Models
4
+ class Channel < Ohm::Model
5
+ attribute :name
6
+
7
+ collection :users, 'Roda::Component::Models::User'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class Roda
2
+ class Component
3
+ module Models
4
+ class User < Ohm::Model
5
+ attribute :model_id
6
+ index :model_id
7
+
8
+ collection :channels, 'Roda::Component::Models::Channel'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ require 'ohm'
2
+ require 'redic'
3
+
4
+ class Roda
5
+ class Component
6
+ Ohm = ::Ohm.dup
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  class Roda
2
2
  class Component
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
@@ -1,5 +1,6 @@
1
1
  unless RUBY_ENGINE == 'opal'
2
2
  require 'tilt'
3
+ require 'awesome_print'
3
4
  end
4
5
 
5
6
  require 'opal'
@@ -18,12 +19,35 @@ if RUBY_ENGINE == 'opal'
18
19
  }
19
20
  end
20
21
 
22
+ module Overrideable
23
+ def self.included(c)
24
+ c.instance_methods(false).each do |m|
25
+ m = m.to_sym
26
+ c.class_eval %Q{
27
+ alias #{m}_original #{m}
28
+ def #{m}(*args, &block)
29
+ puts "Foo"
30
+ result = #{m}_original(*args, &block)
31
+ puts "Bar"
32
+ result
33
+ end
34
+ }
35
+ end
36
+ end
37
+ end
38
+
21
39
  class Roda
22
40
  class Component
23
41
  attr_accessor :scope
24
42
 
25
43
  def initialize(scope = false)
26
44
  @scope = scope
45
+
46
+ if client?
47
+ $faye.subscribe "/components/#{self.class._name}" do |msg|
48
+ `window.console.log(#{msg})`
49
+ end
50
+ end
27
51
  end
28
52
 
29
53
  class << self
@@ -37,6 +61,38 @@ class Roda
37
61
  end
38
62
  end
39
63
 
64
+ def on_server &block
65
+ if server?
66
+ yield
67
+ else
68
+ m = Module.new(&block)
69
+
70
+ m.public_instance_methods(false).each do |meth|
71
+ define_method "#{meth}" do |*args, &blk|
72
+ name = self.class._name
73
+ event_id = "comp-event-#{$faye.generate_id}"
74
+
75
+ Element['body'].on event_id do |event, local, data|
76
+ blk.call local, event, data
77
+ end
78
+
79
+ $faye.publish("/components/outgoing/#{$faye.private_id}/#{$faye.public_id}", {
80
+ name: name,
81
+ type: 'event',
82
+ event_type: 'call',
83
+ event_method: meth,
84
+ event_id: event_id,
85
+ local: args.first || nil
86
+ })
87
+
88
+ true
89
+ end
90
+ end
91
+
92
+ include m
93
+ end
94
+ end
95
+
40
96
  # The name of the component
41
97
  def name _name
42
98
  @_name = _name.to_s
@@ -78,6 +134,7 @@ class Roda
78
134
  unless @_cache
79
135
  @_cache ||= Roda::RodaCache.new
80
136
  @_cache[:tmpl] = {}
137
+ @_cache[:server_methods] = []
81
138
  end
82
139
 
83
140
  @_cache
@@ -146,22 +203,26 @@ class Roda
146
203
  end
147
204
 
148
205
  def dom
149
- @_dom ||= DOM.new cache[:dom].dup || begin
150
- if server?
206
+ if server?
207
+ @_dom ||= DOM.new cache[:dom].dup || begin
151
208
  Nokogiri::HTML cache[:html]
152
- else
153
- Element
154
209
  end
210
+ else
211
+ @_dom ||= DOM.new(Element)
155
212
  end
156
213
  end
157
214
 
158
215
  # Grab the template from the cache, use the nokogiri dom or create a
159
216
  # jquery element for server side
160
217
  def tmpl name
161
- if server?
162
- DOM.new cache[:tmpl][name][:dom].dup
218
+ if t = cache[:tmpl][name]
219
+ if server?
220
+ DOM.new t[:dom].dup
221
+ else
222
+ DOM.new Element[t[:html].dup]
223
+ end
163
224
  else
164
- DOM.new Element[cache[:tmpl][name][:html].dup]
225
+ false
165
226
  end
166
227
  end
167
228
 
@@ -3,6 +3,7 @@ require 'faye'
3
3
  require 'faye/redis'
4
4
  require 'roda/component'
5
5
  require 'roda/component/faye'
6
+ require 'roda/component/ohm'
6
7
  require 'json'
7
8
  require "base64"
8
9
 
@@ -13,12 +14,6 @@ class Roda
13
14
  Faye::WebSocket.load_adapter('thin')
14
15
 
15
16
  app.plugin :csrf, header: 'X-CSRF-TOKEN'
16
-
17
- app.use Faye::RackAdapter,
18
- mount: '/faye',
19
- timeout: 25,
20
- extensions: [Roda::Component::Faye::CsrfProtection.new],
21
- :engine => { :type => Faye::Redis }
22
17
  end
23
18
 
24
19
  def self.configure(app, opts={})
@@ -28,16 +23,33 @@ class Roda
28
23
  app.opts[:component] = opts.dup
29
24
  end
30
25
 
31
- opts = app.opts[:component]
32
- opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, true)
33
- opts[:path] ||= 'components'
34
- opts[:route] ||= 'components'
35
- opts[:assets_route] ||= 'assets/components'
36
- opts[:class] ||= Roda::Component
37
- opts[:settings] ||= {}
38
- opts[:class_name] ||= {}
39
- opts[:events] ||= {}
40
- opts[:cache][:tmpl] ||= {}
26
+ opts = app.opts[:component]
27
+ opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, true)
28
+ opts[:path] ||= 'components'
29
+ opts[:route] ||= 'components'
30
+ opts[:assets_route] ||= 'assets/components'
31
+ opts[:class] ||= Roda::Component
32
+ opts[:settings] ||= {}
33
+ opts[:class_name] ||= {}
34
+ opts[:events] ||= {}
35
+ opts[:user_model] ||= 'User'
36
+ opts[:redis_namespace] ||= 'roda:component:'
37
+ opts[:cache][:tmpl] ||= {}
38
+
39
+ app.use(Faye::RackAdapter, {
40
+ mount: '/faye',
41
+ extensions: [
42
+ Roda::Component::Faye::CsrfProtection.new,
43
+ Roda::Component::Faye::ChannelManager.new
44
+ ],
45
+ engine: {
46
+ type: Faye::Redis,
47
+ uri: opts[:redis_uri],
48
+ namespace: opts[:redis_namespace]
49
+ }
50
+ })
51
+
52
+ Roda::Component::Ohm.redis = Redic.new opts[:redis_uri]
41
53
 
42
54
  # Set the current app
43
55
  opts[:class].set_app app
@@ -66,35 +78,10 @@ class Roda
66
78
  options = Base64.encode64 options.to_json
67
79
  comp_name = comp.class._name
68
80
 
69
- # client.addExtension({
70
- # outgoing: function(message, callback) {
71
- # message.ext = message.ext || {};
72
- # message.ext.csrfToken = $('meta[name=csrf-token]').attr('content');
73
- # callback(message);
74
- # }
75
- # });
76
81
  js = <<-EOF
77
82
  Document.ready? do
78
83
  unless $faye
79
84
  $faye = Roda::Component::Faye.new('/faye')
80
-
81
- $faye.set_header 'X-CSRF-TOKEN', Element.find('meta[name=_csrf]').attr('content')
82
-
83
- $faye.add_extension({
84
- outgoing: ->(message, block) {
85
- message = Native(message)
86
- message.ext = message.ext || {}
87
- message.ext.csrfToken = Element.find('meta[name=_csrf]').attr('content')
88
-
89
- block.call message
90
- }
91
- })
92
-
93
- $faye.subscribe '/foo' do |message|
94
- puts '===================='
95
- puts message
96
- puts '===================='
97
- end
98
85
  end
99
86
 
100
87
  unless $component_opts[:comp][:"#{comp_name}"]
@@ -126,15 +113,19 @@ class Roda
126
113
  end
127
114
  end
128
115
 
129
- if comp_response.is_a? Roda::Component::DOM
130
- content = comp_response.to_html
131
- else
132
- content = comp_response.to_s
133
- end
116
+ if !env['RODA_COMPONENT_FROM_FAYE']
117
+ if comp_response.is_a? Roda::Component::DOM
118
+ content = comp_response.to_html
119
+ else
120
+ content = comp_response.to_s
121
+ end
134
122
 
135
- content += load_component_js comp, action
123
+ content += load_component_js comp, action
136
124
 
137
- content
125
+ content
126
+ else
127
+ comp_response
128
+ end
138
129
  end
139
130
  alias :comp :component
140
131
  alias :roda_component :component
@@ -24,6 +24,9 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency "faye-redis"
25
25
  spec.add_runtime_dependency "tilt"
26
26
  spec.add_runtime_dependency "rack_csrf"
27
+ spec.add_runtime_dependency "ohm"
28
+ spec.add_runtime_dependency "ohm-contrib"
29
+ spec.add_runtime_dependency "ohm-sorted"
27
30
  spec.add_development_dependency "bundler", "~> 1.7"
28
31
  spec.add_development_dependency "rake", "~> 10.0"
29
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda-component
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - cj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-02 00:00:00.000000000 Z
11
+ date: 2014-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -94,6 +94,48 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ohm
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: ohm-contrib
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: ohm-sorted
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  - !ruby/object:Gem::Dependency
98
140
  name: bundler
99
141
  requirement: !ruby/object:Gem::Requirement
@@ -142,6 +184,9 @@ files:
142
184
  - lib/roda/component/events.rb
143
185
  - lib/roda/component/faye.rb
144
186
  - lib/roda/component/instance.rb
187
+ - lib/roda/component/models/channel.rb
188
+ - lib/roda/component/models/user.rb
189
+ - lib/roda/component/ohm.rb
145
190
  - lib/roda/component/version.rb
146
191
  - lib/roda/plugins/component.rb
147
192
  - roda-component.gemspec