opal-connect 0.0.1 → 0.0.2

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: 7ee622b62ef725481b6c98e606815d1498b4f847
4
- data.tar.gz: a27b1855decd4c7af2df0e92974a3be0ee5e9b87
3
+ metadata.gz: a8eb1755efb4187fb0fe313046b83862a7943ac3
4
+ data.tar.gz: fd330a60e16e736d1e5cb29e402ef3b83233a761
5
5
  SHA512:
6
- metadata.gz: fd927ee3c2efe5fa14c11bd096b5f4cf261dedf30160ccb269254754941b679e06cc6659d9b9b649221a8a2d3a2120821ab10a7f689027ef39171623644e3ea1
7
- data.tar.gz: 33dd26a3bef73247df061b1ed8c52751abd04a58bdb2568fc11be8f8e9ed5f2c785f708366085c952d561f07dee66e17b42e3f061d9e151827ccd5499b4eefc8
6
+ metadata.gz: bce04a189804b540bd3382d6de3722ce6e177dd9e7c8b98e2d1e720cc9f9dabf392bf14dd45f60eb7d1a9ec3ef3ed15f75dc47006b9b7e643532857e13cfdc3d
7
+ data.tar.gz: fecc33e53a01ddffb92dea830892eee8f7578d216524011fe3a3f855ea46bfaee70c4086272f136ee287010dbddc83398f17d94bea00305ec56e5ca6c44efe52
data/lib/opal/connect.rb CHANGED
@@ -13,15 +13,33 @@ end
13
13
  # Opal corelib is already loaded from CDN
14
14
  module Opal
15
15
  module Connect
16
+
17
+ CLIENT_OPTIONS = %w'url plugins' unless RUBY_ENGINE == 'opal'
18
+
16
19
  class << self
17
- def __options__
18
- @options ||= Connect::ConnectCache.new(hot_reload: false)
20
+ def options
21
+ @options ||= Connect::ConnectCache.new(
22
+ hot_reload: false,
23
+ url: '/connect',
24
+ plugins: []
25
+ )
26
+ end
27
+
28
+ def options=(opts)
29
+ @options = opts
30
+ end if RUBY_ENGINE == 'opal'
19
31
 
20
- yield(@options) if block_given?
32
+ def setup
33
+ yield(options) if block_given?
21
34
 
22
- @options
35
+ # make sure we include the default plugins with connect
36
+ options[:plugins].each { |plug| Connect.plugin plug.to_sym }
37
+
38
+ unless RUBY_ENGINE == 'opal'
39
+ write_plugins_file
40
+ write_entry_file
41
+ end
23
42
  end
24
- alias options __options__
25
43
 
26
44
  def included(klass)
27
45
  if RUBY_ENGINE != 'opal'
@@ -30,19 +48,21 @@ module Opal
30
48
  end
31
49
 
32
50
  klass.extend ConnectPlugins::Base::ClassMethods
33
- klass.plugin :server
34
- klass.plugin :html
35
- klass.plugin :dom
36
- klass.plugin :events
51
+
52
+ # include default plugins
53
+ Connect.options[:plugins].each { |plug| klass.plugin plug.to_sym }
37
54
  end
38
55
 
56
+ # We need to wripte a plugins.rb file which has all the plugins required
57
+ # by the server, so that the client can require them. Opal doesn't handle
58
+ # dynamically generated imports, which is the reason we make a single file.
39
59
  def write_plugins_file
40
- ConnectPlugins.plugins.each do |name, klass|
41
- path = klass.instance_methods(false).map { |m|
42
- klass.instance_method(m).source_location.first
43
- }.uniq
44
-
45
- binding.pry
60
+ path = "#{Dir.pwd}/.connect/plugins.rb"
61
+ FileUtils.mkdir_p(File.dirname(path))
62
+ File.open(path, 'w+') do |file|
63
+ ConnectPlugins.plugins.each do |name, _|
64
+ file.puts "require 'opal/connect/plugins/#{name}'"
65
+ end
46
66
  end
47
67
  end
48
68
  end
@@ -78,6 +98,14 @@ module Opal
78
98
  @mutex.synchronize { @hash.to_json }
79
99
  end
80
100
 
101
+ def hash
102
+ if RUBY_ENGINE == 'opal'
103
+ @hash
104
+ else
105
+ @mutex.synchronize { @hash }
106
+ end
107
+ end
108
+
81
109
  def each
82
110
  if RUBY_ENGINE == 'opal'
83
111
  @hash.each { |key, value| yield key, value }
@@ -152,8 +180,8 @@ module Opal
152
180
  plugin.load_dependencies(self, *args, &block) if plugin.respond_to?(:load_dependencies)
153
181
  include(plugin::InstanceMethods) if defined?(plugin::InstanceMethods)
154
182
  extend(plugin::ClassMethods) if defined?(plugin::ClassMethods)
155
- self.extend(plugin::ConnectClassMethods) if defined?(plugin::ConnectClassMethods)
156
- self.include(plugin::ConnectInstanceMethods) if defined?(plugin::ConnectInstanceMethods)
183
+ Connect.extend(plugin::ConnectClassMethods) if defined?(plugin::ConnectClassMethods)
184
+ Connect.include(plugin::ConnectInstanceMethods) if defined?(plugin::ConnectInstanceMethods)
157
185
  plugin.configure(self, *args, &block) if plugin.respond_to?(:configure)
158
186
  nil
159
187
  end
@@ -166,21 +194,13 @@ module Opal
166
194
  def build(code)
167
195
  builder = Opal::Builder.new
168
196
 
169
- builder.build_str(code, '(inline)' \
170
- , dynamic_require_severity: :ignore).to_s
197
+ builder.build_str(code, '(inline)').to_s
171
198
  end
172
199
 
173
200
  def javascript(klass, method, *options)
174
- if hot_reload = Connect.options[:hot_reload]
175
- required_files = Connect.files.map do |file|
176
- "`require('#{file}')`"
177
- end.join(';')
178
- end
201
+ return unless klass
179
202
 
180
203
  %{
181
- #{!hot_reload ? '' : 'Opal::Connect.events_teardown'}
182
- #{!hot_reload ? '' : required_files}
183
-
184
204
  Opal::Connect.server_methods = JSON.parse(
185
205
  Base64.decode64('#{Base64.encode64 Connect.server_methods.to_json}')
186
206
  )
@@ -197,17 +217,41 @@ module Opal
197
217
  }
198
218
  end
199
219
 
200
- def write_entry_file(klass, method, *options)
220
+ def write_entry_file(klass = false, method = false, *options)
201
221
  Opal.use_gem 'opal-jquery'
202
222
 
203
- code = %{
204
- `if (module.hot) {`
205
- `module.hot.accept()`
206
- #{Connect.javascript(klass, method, *options)}
207
- `}`
208
- }
223
+ path = "#{Dir.pwd}/.connect/entry.js"
224
+
225
+ required_files = Connect.files.map do |file|
226
+ "`require('#{file}')`"
227
+ end.join(';')
228
+
229
+ client_options = Connect.options.hash.select do |key, _|
230
+ CLIENT_OPTIONS.include? key.to_s
231
+ end
232
+
233
+ client_options = Base64.encode64 client_options.to_json
234
+ templates = Base64.encode64 Connect.templates.hash.to_json
235
+
236
+ code = "Opal::Connect.options = JSON.parse(Base64.decode64('#{client_options}'));"
237
+ code = "#{code} Opal::Connect.setup;"
238
+ code = "#{code} Opal::Connect.templates = JSON.parse(Base64.decode64('#{templates}'));"
239
+
240
+ if !Connect.options[:hot_reload]
241
+ code = "#{code} #{required_files}"
242
+ else
243
+ code << %{
244
+ `if (module.hot) {`
245
+ `module.hot.accept()`
246
+ #{required_files}
247
+ Opal::Connect.events_teardown
248
+ #{Connect.javascript(klass, method, *options)}
249
+ `}`
250
+ }
251
+ end
209
252
 
210
- File.write("#{Dir.pwd}/.connect/entry.js", build(code))
253
+ FileUtils.mkdir_p(File.dirname(path))
254
+ File.write(path, build(code))
211
255
  end
212
256
  end
213
257
  end
@@ -220,7 +264,5 @@ module Opal
220
264
 
221
265
  extend ConnectPlugins::Base::ClassMethods
222
266
  plugin ConnectPlugins::Base
223
- plugin :server
224
- plugin :events
225
267
  end
226
268
  end
@@ -9,45 +9,72 @@ module Opal
9
9
  # A thread safe cache class, offering only #[] and #[]= methods,
10
10
  # each protected by a mutex.
11
11
  module Dom
12
- extend self
12
+ module ConnectClassMethods
13
+ def templates
14
+ @templates ||= ConnectCache.new
15
+ end
13
16
 
14
- if RUBY_ENGINE != 'opal'
15
- def html_file(caller)
16
- path = "#{Dir.pwd}/.connect/html/#{caller[0][/[^:]*/].sub(Dir.pwd, '')[1..-1].sub('.rb', '.html')}"
17
- FileUtils.mkdir_p(File.dirname(path))
18
- path
17
+ if RUBY_ENGINE == 'opal'
18
+ def templates=(tmpls)
19
+ @templates = tmpls
20
+ end
19
21
  end
20
22
  end
21
23
 
22
- def html(scope = false, &block)
23
- if !block_given?
24
- HTML::DSL.html(&scope).to_html
25
- else
26
- HTML::DSL.scope!(scope).html(&block).to_html
24
+ module ClassMethods
25
+ if RUBY_ENGINE != 'opal'
26
+ def html_file(caller)
27
+ path = "#{Dir.pwd}/.connect/html/#{caller[0][/[^:]*/].sub(Dir.pwd, '')[1..-1].sub('.rb', '.html')}"
28
+ FileUtils.mkdir_p(File.dirname(path))
29
+ path
30
+ end
27
31
  end
28
- end
29
32
 
30
- def [](selector)
31
- if RUBY_ENGINE == 'opal'
32
- file_name = false
33
- else
34
- file_name = html_file(caller)
33
+ def cache
34
+ @cache ||= (Connect.templates[self.name] ||= {})
35
+ end
35
36
 
36
- if selector.is_a?(Symbol)
37
- file_name = "#{file_name}.#{selector}"
38
- selector = File.read(file_name)
37
+ def html(scope = false, &block)
38
+ if !block_given?
39
+ HTML::DSL.html(&scope).to_html
40
+ else
41
+ HTML::DSL.scope!(scope).html(&block).to_html
39
42
  end
40
43
  end
41
44
 
42
- Instance.new selector, file_name
45
+ def dom
46
+ if RUBY_ENGINE == 'opal'
47
+ selector = 'html'
48
+ else
49
+ selector = false
50
+ end
51
+
52
+ @dom ||= Instance.new false, cache
53
+ end
54
+ end
55
+
56
+ module InstanceMethods
57
+ def cache
58
+ self.class.cache
59
+ end
60
+
61
+ def dom
62
+ if RUBY_ENGINE == 'opal'
63
+ selector = 'html'
64
+ else
65
+ selector = cache[:html]
66
+ end
67
+
68
+ @dom ||= Instance.new selector, cache
69
+ end
43
70
  end
44
71
 
45
72
  class Instance
46
- attr_reader :selector, :file_name, :dom
73
+ attr_reader :selector, :cache, :dom
47
74
 
48
- def initialize(selector, file_name = false)
49
- @selector = selector
50
- @file_name = file_name
75
+ def initialize(selector, cache)
76
+ @selector = selector
77
+ @cache = cache
51
78
 
52
79
  if selector.is_a?(String)
53
80
  if RUBY_ENGINE == 'opal'
@@ -57,7 +84,7 @@ module Opal
57
84
  if selector["\n"]
58
85
  @dom = Oga.parse_html(selector)
59
86
  else
60
- @dom = Oga.parse_html(File.read(file_name))
87
+ @dom = cache[:html]
61
88
  @dom = dom.css(selector) unless selector == 'html'
62
89
  end
63
90
  end
@@ -66,15 +93,34 @@ module Opal
66
93
  end
67
94
  end
68
95
 
69
- if RUBY_ENGINE != 'opal'
70
- def to_html
96
+ def set html
97
+ @dom = Instance.new(html, cache)
98
+ end
99
+ alias set! set
100
+
101
+ def save template_name = false, remove = true
102
+ if template_name
103
+ cache[:"#{template_name}"] = self.to_html
104
+ dom.remove if remove
105
+ else
106
+ cache[:html] = self.to_html
107
+ end
108
+ end
109
+ alias save! save
110
+
111
+ def to_html
112
+ if RUBY_ENGINE == 'opal'
113
+ node.html
114
+ else
71
115
  if node.respond_to?(:first)
72
116
  node.first.to_xml
73
117
  else
74
118
  node.to_xml
75
119
  end
76
120
  end
121
+ end
77
122
 
123
+ if RUBY_ENGINE != 'opal'
78
124
  def to_s
79
125
  if dom.respond_to?(:first)
80
126
  dom.first.to_xml
@@ -83,16 +129,6 @@ module Opal
83
129
  end
84
130
  end
85
131
 
86
- def save template_name = false, remove = true
87
- if template_name
88
- File.write("#{file_name}.#{template_name.to_s}", self.to_html)
89
- dom.remove if remove
90
- else
91
- File.write(file_name, self.to_html)
92
- end
93
- end
94
- alias save! save
95
-
96
132
  def text(content)
97
133
  if node.respond_to?(:inner_text)
98
134
  node.inner_text = content
@@ -132,6 +168,14 @@ module Opal
132
168
  end
133
169
  end
134
170
 
171
+ def tmpl(name)
172
+ if cached_tmpl = cache[:"#{name}"]
173
+ Instance.new(cached_tmpl, cache)
174
+ else
175
+ puts "There is no template `#{name}`"
176
+ end
177
+ end
178
+
135
179
  def append(content, &block)
136
180
  # content becomes scope in this case
137
181
  content = HTML::DSL.scope!(content).html(&block).to_html if block_given?
@@ -212,11 +256,11 @@ module Opal
212
256
  end
213
257
  end
214
258
 
215
- Instance.new(new_node, file_name)
259
+ Instance.new(new_node, cache)
216
260
  end
217
261
 
218
262
  def each
219
- node.each { |n| yield Instance.new(n, file_name) }
263
+ node.each { |n| yield Instance.new(n, cache) }
220
264
  end
221
265
 
222
266
  def node
@@ -243,5 +287,3 @@ module Opal
243
287
  end
244
288
  end
245
289
  end
246
-
247
- Dom = Opal::Connect::ConnectPlugins::Dom
@@ -9,18 +9,21 @@ module Opal
9
9
  end
10
10
  end
11
11
 
12
- def connect_el el = false
12
+ def __events_el__ el = false
13
13
  @connect_el = el if el
14
14
  @connect_el
15
15
  end
16
+ alias events_el __events_el__
16
17
 
17
- def connect_on(name, selector = nil, method = nil, &handler)
18
+
19
+ def __on__(name, selector = nil, method = nil, &handler)
18
20
  if RUBY_ENGINE == 'opal'
19
21
  handler = proc { |evt| __send__(method, evt) } if method
20
22
  event = [name, selector, handler]
21
23
  connect_events << event unless connect_events.include? event
22
24
  end
23
25
  end
26
+ alias on __on__
24
27
  end
25
28
 
26
29
  if RUBY_ENGINE == 'opal'
@@ -0,0 +1,29 @@
1
+ module Opal
2
+ module Connect
3
+ module ConnectPlugins
4
+ module Scope
5
+ module InstanceMethods
6
+ def scope(new_scope = false)
7
+ if new_scope
8
+ @scope = new_scope
9
+
10
+ self
11
+ else
12
+ @scope
13
+ end
14
+ end
15
+
16
+ def method_missing(method, *args, &block)
17
+ if scope.respond_to?(method, true)
18
+ scope.send(method, *args, &block)
19
+ else
20
+ super
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ register_plugin :scope, Scope
27
+ end
28
+ end
29
+ end
@@ -17,7 +17,7 @@ module Opal
17
17
  Connect.server_methods[self.name] ||= []
18
18
  end
19
19
 
20
- def connect_server(m = false, &block)
20
+ def __server__(m = false, &block)
21
21
  return if RUBY_ENGINE == 'opal'
22
22
 
23
23
  m ||= Module.new(&block)
@@ -28,10 +28,11 @@ module Opal
28
28
  connect_server_methods << meth unless connect_server_methods.include? meth
29
29
  end
30
30
  end
31
+ alias server __server__
31
32
  end
32
33
 
33
- module ConnectInstanceMethods
34
- def __connect_server__(method, *args)
34
+ module InstanceMethods
35
+ def __server__(method, *args)
35
36
  if Connect.server_methods[self.class.name].include? method
36
37
  promise = Promise.new
37
38
 
@@ -41,7 +42,7 @@ module Opal
41
42
  klass: self.class.name
42
43
  }
43
44
 
44
- HTTP.post('/connect', payload: payload) do |response|
45
+ HTTP.post(Connect.options[:url], payload: payload) do |response|
45
46
  if response.ok?
46
47
  res = JSON.from_object(`response`)
47
48
  promise.resolve res[:body], response
@@ -55,7 +56,7 @@ module Opal
55
56
  raise "#{method} is not a server method"
56
57
  end
57
58
  end
58
- alias connect_server __connect_server__
59
+ alias server __server__
59
60
  end
60
61
  end
61
62
 
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Connect
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - cj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-18 00:00:00.000000000 Z
11
+ date: 2016-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -96,6 +96,7 @@ files:
96
96
  - lib/opal/connect/plugins/dom.rb
97
97
  - lib/opal/connect/plugins/events.rb
98
98
  - lib/opal/connect/plugins/html.rb
99
+ - lib/opal/connect/plugins/scope.rb
99
100
  - lib/opal/connect/plugins/server.rb
100
101
  - lib/opal/connect/version.rb
101
102
  - opal-connect.gemspec