pakyow-ui 0.11.3 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/{pakyow-ui/CHANGELOG.md → CHANGELOG.md} +0 -0
  3. data/LICENSE +4 -0
  4. data/{pakyow-ui/README.md → README.md} +1 -2
  5. data/lib/pakyow/ui/behavior/recording.rb +51 -0
  6. data/lib/pakyow/ui/behavior/rendering/install_transforms.rb +47 -0
  7. data/lib/pakyow/ui/behavior/rendering.rb +105 -0
  8. data/lib/pakyow/ui/behavior/timeouts.rb +31 -0
  9. data/lib/pakyow/ui/framework.rb +75 -0
  10. data/lib/pakyow/ui/handler.rb +42 -0
  11. data/lib/pakyow/ui/helpers.rb +19 -0
  12. data/lib/pakyow/ui/recordable/attribute.rb +39 -0
  13. data/lib/pakyow/ui/recordable/attributes.rb +50 -0
  14. data/lib/pakyow/ui/recordable/helpers/client_remapping.rb +30 -0
  15. data/lib/pakyow/ui/recordable.rb +303 -0
  16. data/lib/pakyow/ui.rb +9 -0
  17. metadata +46 -60
  18. data/pakyow-ui/LICENSE +0 -20
  19. data/pakyow-ui/lib/pakyow/ui/base.rb +0 -26
  20. data/pakyow-ui/lib/pakyow/ui/channel_builder.rb +0 -55
  21. data/pakyow-ui/lib/pakyow/ui/config.rb +0 -11
  22. data/pakyow-ui/lib/pakyow/ui/ext/app.rb +0 -52
  23. data/pakyow-ui/lib/pakyow/ui/ext/view_context.rb +0 -30
  24. data/pakyow-ui/lib/pakyow/ui/fetch_view_handler.rb +0 -68
  25. data/pakyow-ui/lib/pakyow/ui/helpers.rb +0 -15
  26. data/pakyow-ui/lib/pakyow/ui/mock_mutation_eval.rb +0 -25
  27. data/pakyow-ui/lib/pakyow/ui/mutable.rb +0 -99
  28. data/pakyow-ui/lib/pakyow/ui/mutable_data.rb +0 -21
  29. data/pakyow-ui/lib/pakyow/ui/mutate_context.rb +0 -64
  30. data/pakyow-ui/lib/pakyow/ui/mutation_set.rb +0 -38
  31. data/pakyow-ui/lib/pakyow/ui/mutation_store.rb +0 -41
  32. data/pakyow-ui/lib/pakyow/ui/mutator.rb +0 -63
  33. data/pakyow-ui/lib/pakyow/ui/no_op_view.rb +0 -87
  34. data/pakyow-ui/lib/pakyow/ui/registries/redis_mutation_registry.rb +0 -70
  35. data/pakyow-ui/lib/pakyow/ui/registries/simple_mutation_registry.rb +0 -37
  36. data/pakyow-ui/lib/pakyow/ui/ui.rb +0 -81
  37. data/pakyow-ui/lib/pakyow/ui/ui_attrs.rb +0 -40
  38. data/pakyow-ui/lib/pakyow/ui/ui_component.rb +0 -68
  39. data/pakyow-ui/lib/pakyow/ui/ui_context.rb +0 -16
  40. data/pakyow-ui/lib/pakyow/ui/ui_instructable.rb +0 -117
  41. data/pakyow-ui/lib/pakyow/ui/ui_request.rb +0 -14
  42. data/pakyow-ui/lib/pakyow/ui/ui_view.rb +0 -200
  43. data/pakyow-ui/lib/pakyow/ui.rb +0 -1
  44. data/pakyow-ui/lib/pakyow-ui.rb +0 -1
@@ -0,0 +1,303 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ require "pakyow/support/core_refinements/array/ensurable"
6
+
7
+ require "pakyow/support/extension"
8
+ require "pakyow/support/inflector"
9
+ require "pakyow/support/safe_string"
10
+
11
+ require "pakyow/data/sources/relational"
12
+
13
+ require "pakyow/presenter/binding_parts"
14
+ require "pakyow/presenter/versioned_view"
15
+ require "pakyow/presenter/presenter"
16
+
17
+ require "pakyow/ui/recordable/helpers/client_remapping"
18
+ require "pakyow/ui/recordable/attributes"
19
+
20
+ module Pakyow
21
+ module UI
22
+ module Recordable
23
+ extend Support::Extension
24
+
25
+ include Support::SafeStringHelpers
26
+
27
+ using Support::Refinements::Array::Ensurable
28
+
29
+ # @api private
30
+ attr_reader :calls
31
+
32
+ def to_json(*)
33
+ optimized.to_json
34
+ end
35
+
36
+ def to_a
37
+ @calls
38
+ end
39
+
40
+ # @api private
41
+ def cache_bindings!
42
+ binding_nodes = if (view.object.is_a?(StringDoc::Node) || view.object.is_a?(StringDoc::MetaNode)) && view.object.significant?(:multipart_binding)
43
+ [view.object]
44
+ else
45
+ view.object.find_significant_nodes(:binding)
46
+ end
47
+
48
+ @bindings = binding_nodes.flat_map { |node|
49
+ [node.label(:binding), node.label(:binding_prop)]
50
+ }.compact
51
+ end
52
+
53
+ private
54
+
55
+ def optimized
56
+ calls = []
57
+
58
+ # Combine finds when looking for the same nodes.
59
+ #
60
+ @calls.each do |call|
61
+ if call[0] == :find && matching_call = calls.find { |c| c[0] == :find && c[1] == call[1] && c[2] == call[2] }
62
+ matching_call[3].to_a.concat(call[3].to_a)
63
+ else
64
+ calls << call
65
+ end
66
+ end
67
+
68
+ # Prioritize the calls so they are applied correctly on the client.
69
+ #
70
+ calls.sort! { |a, b|
71
+ call_priority(a, calls) <=> call_priority(b, calls)
72
+ }
73
+
74
+ calls
75
+ end
76
+
77
+ PRIORITY_CALLS = %i(transform use).freeze
78
+
79
+ def call_priority(call, calls)
80
+ if PRIORITY_CALLS.include?(call[0])
81
+ # Set priority calls to a priority of -1000, which is highest priority.
82
+ #
83
+ -1000
84
+ elsif call[0] == :find
85
+ # Make priority of finds an inverse of specificity (e.g. [:post] > [:post, :title]).
86
+ #
87
+ -1000 + call[1][0].count
88
+ else
89
+ # Or just keep the same order we have now.
90
+ #
91
+ calls.index(call)
92
+ end
93
+ end
94
+
95
+ # FIXME: We currently viewify twice for present; once for transform, another for bind.
96
+ # Let's create a `Viewified` object instead... then check to see if it's already happened.
97
+ #
98
+ def viewify(data)
99
+ data = if data.is_a?(Data::Proxy)
100
+ data.to_a
101
+ elsif data.nil?
102
+ []
103
+ else
104
+ Array.ensure(data)
105
+ end
106
+
107
+ data.map { |object|
108
+ binder = wrap_data_in_binder(object)
109
+ object = binder.object
110
+
111
+ # Map object keys to the binding name.
112
+ #
113
+ keys_and_binding_names = object.to_h.keys.map { |key|
114
+ key = key.to_sym
115
+ if key == :id || @bindings.include?(key)
116
+ binding_name = key
117
+ else
118
+ plural_binding_name = Support.inflector.pluralize(key.to_s).to_sym
119
+ singular_binding_name = Support.inflector.singularize(key.to_s).to_sym
120
+
121
+ if @bindings.include?(plural_binding_name)
122
+ binding_name = plural_binding_name
123
+ elsif @bindings.include?(singular_binding_name)
124
+ binding_name = singular_binding_name
125
+ else
126
+ next
127
+ end
128
+ end
129
+
130
+ [key, binding_name]
131
+ }
132
+
133
+ # Add view-specific bindings that aren't in the object, but may exist in the binder.
134
+ #
135
+ @bindings.each do |binding_name|
136
+ unless keys_and_binding_names.find { |_, k2| k2 == binding_name }
137
+ keys_and_binding_names << [binding_name, binding_name]
138
+ end
139
+ end
140
+
141
+ viewified = keys_and_binding_names.compact.uniq.each_with_object({}) { |(key, binding_name), values|
142
+ value = binder.__value(key)
143
+
144
+ if value.is_a?(String)
145
+ value = ensure_html_safety(value)
146
+ end
147
+
148
+ if value.is_a?(Presenter::BindingParts)
149
+ values[binding_name] = value.values(@view.find(binding_name))
150
+ elsif !value.nil?
151
+ values[binding_name] = value
152
+ end
153
+ }
154
+
155
+ viewified
156
+ }
157
+ end
158
+
159
+ apply_extension do
160
+ include Helpers::ClientRemapping
161
+ end
162
+
163
+ def self.find_through(binding_path, binding_info, options, context, calls)
164
+ if binding_path.any?
165
+ binding_path_part = binding_path.shift
166
+ current_options = options.dup
167
+
168
+ if id = binding_info[binding_path_part.to_s.split(":", 2)[0].to_sym]
169
+ # Tie the transformations to a node of a specific id, unless we're transforming the entire set.
170
+ #
171
+ unless calls.any? { |call| call[0] == :transform }
172
+ current_options["id"] = id
173
+ end
174
+ end
175
+
176
+ subsequent = []
177
+
178
+ args = [[binding_path_part]]
179
+ unless current_options.empty?
180
+ args << current_options
181
+ end
182
+
183
+ context << [
184
+ :find,
185
+ args, [], subsequent
186
+ ]
187
+
188
+ find_through(binding_path, binding_info, options, subsequent, calls)
189
+ else
190
+ context.concat(calls)
191
+ end
192
+ end
193
+
194
+ class_methods do
195
+ def render_proc(view, render, &block)
196
+ super(view, render) do |_, context|
197
+ if render[:node]
198
+ instance_exec(&block)
199
+
200
+ # The super proc creates a new presenter instance per render, but we want each to use the
201
+ # same starting point for calls since they all apply to the same node.
202
+ #
203
+ context.calls.concat(calls)
204
+ else
205
+ instance_exec(&block)
206
+
207
+ if calls.any?
208
+ # Explicitly find the node to apply the transformation to the correct node. While
209
+ # we're at it, append any transformations caused by the `instance_exec` above.
210
+ #
211
+ Recordable.find_through(
212
+ render[:binding_path].dup, object.label(:binding_info).to_h, {}, context.calls, calls
213
+ )
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ def from_presenter(presenter)
220
+ allocate.tap { |instance|
221
+ # Copy state from the presenter we're tracking.
222
+ #
223
+ presenter.instance_variables.each do |ivar|
224
+ instance.instance_variable_set(ivar, presenter.instance_variable_get(ivar))
225
+ end
226
+
227
+ instance.cache_bindings!
228
+ }
229
+ end
230
+ end
231
+
232
+ prepend_methods do
233
+ def initialize(*)
234
+ super
235
+
236
+ @calls = []
237
+ cache_bindings!
238
+ end
239
+
240
+ def presenter_for(view, type: view&.label(:presenter_type))
241
+ presenter = super
242
+
243
+ if presenter.is_a?(Delegator)
244
+ presenter.__setobj__(self.class.from_presenter(presenter.__getobj__))
245
+ else
246
+ presenter = self.class.from_presenter(presenter)
247
+ end
248
+
249
+ presenter
250
+ end
251
+
252
+ %i(
253
+ find transform use bind append prepend after before replace remove clear title= html=
254
+ endpoint endpoint_action component
255
+ ).each do |method_name|
256
+ define_method method_name do |*args, &block|
257
+ nested = []
258
+
259
+ super(*args) { |nested_presenter, *nested_args|
260
+ if block
261
+ nested << nested_presenter
262
+ block.call(nested_presenter, *nested_args)
263
+ end
264
+ }.tap do |result|
265
+ call_args = case method_name
266
+ when :find
267
+ # Because multiple bindings can be passed, we want to wrap them in
268
+ # an array so that the client sees them as a single argument.
269
+ #
270
+ [args]
271
+ when :transform
272
+ # Ignore the potential `yield_block` argument that's used internally.
273
+ #
274
+ [viewify(args[0])]
275
+ when :bind
276
+ # Modify the bound data to include only necessary values.
277
+ #
278
+ viewify(args)
279
+ else
280
+ args
281
+ end
282
+
283
+ subsequent = if (result.is_a?(Presenter::Presenter) && !result.equal?(self)) || (result.is_a?(Delegator) && !result.__getobj__.equal?(self)) || result.is_a?(Attributes)
284
+ result
285
+ else
286
+ []
287
+ end
288
+
289
+ calls << [remap_for_client(method_name), call_args, nested, subsequent]
290
+ end
291
+ end
292
+ end
293
+
294
+ def attributes
295
+ Attributes.from_attributes(super).tap do |subsequent|
296
+ calls << [:attributes, [], [], subsequent]
297
+ end
298
+ end
299
+ alias attrs attributes
300
+ end
301
+ end
302
+ end
303
+ end
data/lib/pakyow/ui.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pakyow/support"
4
+ require "pakyow/routing"
5
+ require "pakyow/data"
6
+ require "pakyow/presenter"
7
+ require "pakyow/realtime"
8
+
9
+ require "pakyow/ui/framework"
metadata CHANGED
@@ -1,155 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pakyow-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.3
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-15 00:00:00.000000000 Z
11
+ date: 2019-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: pakyow-support
14
+ name: pakyow-core
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.11.3
19
+ version: 1.0.0.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.11.3
26
+ version: 1.0.0.rc1
27
27
  - !ruby/object:Gem::Dependency
28
- name: pakyow-core
28
+ name: pakyow-data
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 0.11.3
33
+ version: 1.0.0.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 0.11.3
40
+ version: 1.0.0.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pakyow-presenter
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 0.11.3
47
+ version: 1.0.0.rc1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 0.11.3
54
+ version: 1.0.0.rc1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pakyow-realtime
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.11.3
61
+ version: 1.0.0.rc1
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.11.3
68
+ version: 1.0.0.rc1
69
69
  - !ruby/object:Gem::Dependency
70
- name: minitest
70
+ name: pakyow-routing
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: '5.6'
76
- type: :development
75
+ version: 1.0.0.rc1
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: '5.6'
82
+ version: 1.0.0.rc1
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec
84
+ name: pakyow-support
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: '3.2'
90
- type: :development
89
+ version: 1.0.0.rc1
90
+ type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: '3.2'
96
+ version: 1.0.0.rc1
97
97
  description: Auto-Updating UIs for Pakyow
98
98
  email: bryan@metabahn.com
99
99
  executables: []
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
- - pakyow-ui/CHANGELOG.md
104
- - pakyow-ui/LICENSE
105
- - pakyow-ui/README.md
106
- - pakyow-ui/lib/pakyow-ui.rb
107
- - pakyow-ui/lib/pakyow/ui.rb
108
- - pakyow-ui/lib/pakyow/ui/base.rb
109
- - pakyow-ui/lib/pakyow/ui/channel_builder.rb
110
- - pakyow-ui/lib/pakyow/ui/config.rb
111
- - pakyow-ui/lib/pakyow/ui/ext/app.rb
112
- - pakyow-ui/lib/pakyow/ui/ext/view_context.rb
113
- - pakyow-ui/lib/pakyow/ui/fetch_view_handler.rb
114
- - pakyow-ui/lib/pakyow/ui/helpers.rb
115
- - pakyow-ui/lib/pakyow/ui/mock_mutation_eval.rb
116
- - pakyow-ui/lib/pakyow/ui/mutable.rb
117
- - pakyow-ui/lib/pakyow/ui/mutable_data.rb
118
- - pakyow-ui/lib/pakyow/ui/mutate_context.rb
119
- - pakyow-ui/lib/pakyow/ui/mutation_set.rb
120
- - pakyow-ui/lib/pakyow/ui/mutation_store.rb
121
- - pakyow-ui/lib/pakyow/ui/mutator.rb
122
- - pakyow-ui/lib/pakyow/ui/no_op_view.rb
123
- - pakyow-ui/lib/pakyow/ui/registries/redis_mutation_registry.rb
124
- - pakyow-ui/lib/pakyow/ui/registries/simple_mutation_registry.rb
125
- - pakyow-ui/lib/pakyow/ui/ui.rb
126
- - pakyow-ui/lib/pakyow/ui/ui_attrs.rb
127
- - pakyow-ui/lib/pakyow/ui/ui_component.rb
128
- - pakyow-ui/lib/pakyow/ui/ui_context.rb
129
- - pakyow-ui/lib/pakyow/ui/ui_instructable.rb
130
- - pakyow-ui/lib/pakyow/ui/ui_request.rb
131
- - pakyow-ui/lib/pakyow/ui/ui_view.rb
132
- homepage: http://pakyow.org
103
+ - CHANGELOG.md
104
+ - LICENSE
105
+ - README.md
106
+ - lib/pakyow/ui.rb
107
+ - lib/pakyow/ui/behavior/recording.rb
108
+ - lib/pakyow/ui/behavior/rendering.rb
109
+ - lib/pakyow/ui/behavior/rendering/install_transforms.rb
110
+ - lib/pakyow/ui/behavior/timeouts.rb
111
+ - lib/pakyow/ui/framework.rb
112
+ - lib/pakyow/ui/handler.rb
113
+ - lib/pakyow/ui/helpers.rb
114
+ - lib/pakyow/ui/recordable.rb
115
+ - lib/pakyow/ui/recordable/attribute.rb
116
+ - lib/pakyow/ui/recordable/attributes.rb
117
+ - lib/pakyow/ui/recordable/helpers/client_remapping.rb
118
+ homepage: https://pakyow.org
133
119
  licenses:
134
- - MIT
120
+ - LGPL-3.0
135
121
  metadata: {}
136
122
  post_install_message:
137
123
  rdoc_options: []
138
124
  require_paths:
139
- - pakyow-ui/lib
125
+ - lib
140
126
  required_ruby_version: !ruby/object:Gem::Requirement
141
127
  requirements:
142
128
  - - ">="
143
129
  - !ruby/object:Gem::Version
144
- version: 2.0.0
130
+ version: 2.5.0
145
131
  required_rubygems_version: !ruby/object:Gem::Requirement
146
132
  requirements:
147
- - - ">="
133
+ - - ">"
148
134
  - !ruby/object:Gem::Version
149
- version: '0'
135
+ version: 1.3.1
150
136
  requirements: []
151
137
  rubyforge_project:
152
- rubygems_version: 2.5.1
138
+ rubygems_version: 2.7.6
153
139
  signing_key:
154
140
  specification_version: 4
155
141
  summary: Pakyow UI
data/pakyow-ui/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2015 Bryan Powell
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,26 +0,0 @@
1
- require_relative 'helpers'
2
- require_relative 'ui'
3
- require_relative 'mutator'
4
- require_relative 'mutation_set'
5
- require_relative 'mutable'
6
- require_relative 'mutate_context'
7
- require_relative 'ui_view'
8
- require_relative 'channel_builder'
9
- require_relative 'fetch_view_handler'
10
- require_relative 'mutation_store'
11
- require_relative 'registries/simple_mutation_registry'
12
- require_relative 'registries/redis_mutation_registry'
13
- require_relative 'config'
14
- require_relative 'ui_component'
15
- require_relative 'ui_instructable'
16
-
17
- require_relative 'ext/app'
18
- require_relative 'ext/view_context'
19
-
20
- Pakyow::App.before :init do
21
- @ui = Pakyow::UI::UI.new
22
- end
23
-
24
- Pakyow::App.after :load do
25
- @ui.load(mutators, mutables)
26
- end
@@ -1,55 +0,0 @@
1
- module Pakyow
2
- module UI
3
- # Helpers for building channel names.
4
- #
5
- # @api private
6
- module ChannelBuilder
7
- PARTS = [:scope, :mutation, :component]
8
-
9
- def self.build(qualifiers: [], data: [], qualifications: {}, **args)
10
- channel = []
11
- channel_extras = []
12
-
13
- PARTS.each do |part|
14
- add_part(part, args[part], channel)
15
- end
16
-
17
- add_qualifiers(qualifiers, data, channel_extras)
18
- add_qualifications(qualifications, channel_extras)
19
-
20
- channel = channel.join(';')
21
-
22
- return channel if channel_extras.empty?
23
- channel << "::#{channel_extras.join(';')}"
24
- end
25
-
26
- private
27
-
28
- def self.add_part(part, value, channel)
29
- return if value.nil?
30
- channel << "#{part}:#{value}"
31
- end
32
-
33
- def self.add_qualifiers(qualifiers, data, channel_extras)
34
- qualifiers = Array.ensure(qualifiers)
35
-
36
- data = data.data if data.is_a?(Pakyow::UI::MutableData)
37
- data = Array.ensure(data).compact
38
- return if qualifiers.empty? || data.empty?
39
-
40
- datum = data.first
41
-
42
- qualifiers.each do |qualifier|
43
- channel_extras << "#{qualifier}:#{datum[qualifier.to_sym]}"
44
- end
45
- end
46
-
47
- def self.add_qualifications(qualifications, channel_extras)
48
- qualifications.each do |name, value|
49
- next if value.nil?
50
- channel_extras << "#{name}:#{value}"
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,11 +0,0 @@
1
- require_relative 'registries/simple_mutation_registry'
2
- require_relative 'registries/redis_mutation_registry'
3
-
4
- Pakyow::Config.register :ui do |config|
5
- # The registry to use when keeping up with connections.
6
- config.opt :registry, Pakyow::UI::SimpleMutationRegistry
7
- end.env :development do |opts|
8
- opts.registry = Pakyow::UI::SimpleMutationRegistry
9
- end.env :production do |opts|
10
- opts.registry = Pakyow::UI::RedisMutationRegistry
11
- end
@@ -1,52 +0,0 @@
1
- module Pakyow
2
- class App
3
- attr_reader :ui
4
-
5
- class << self
6
- # Defines mutators for a scope.
7
- #
8
- # @api public
9
- def mutators(scope = nil, &block)
10
- @mutators ||= {}
11
-
12
- if scope && block
13
- @mutators[scope] = block
14
- else
15
- @mutators || {}
16
- end
17
- end
18
-
19
- # Defines a mutable object.
20
- #
21
- # @api public
22
- def mutable(scope, &block)
23
- @mutables ||= {}
24
- @mutables[scope] = block
25
- end
26
-
27
- # @api private
28
- def mutables
29
- @mutables || {}
30
- end
31
- end
32
-
33
- # Convenience method for defining mutators on an app instance.
34
- #
35
- # @api public
36
- def mutators(scope = nil, &block)
37
- self.class.mutators(scope, &block)
38
- end
39
-
40
- # Convenience method for defining a mutable on an app instance.
41
- #
42
- # @api public
43
- def mutable(scope, &block)
44
- self.class.mutable(scope, &block)
45
- end
46
-
47
- # @api private
48
- def mutables
49
- self.class.mutables
50
- end
51
- end
52
- end