pakyow-ui 0.11.3 → 1.0.0.rc1

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