roda-component 0.0.5 → 0.0.6

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.
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