volt 0.4.9 → 0.4.10

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.
@@ -1,72 +0,0 @@
1
- require 'volt/models/params_array'
2
-
3
- # All url related data is stored in params. This includes the main uri
4
- # in addition to any query parameters. The router is responsible for
5
- # converting any uri sections into params. Sections in the uri will
6
- # override any specified parameters.
7
- #
8
- # The params value can be updated the same way a model would be, only
9
- # the updates will trigger an updated url via the browser history api.
10
- # TODO: Support # for browsers without the history api.
11
- class Params < Model
12
- def initialize(*args)
13
- super(*args)
14
- end
15
-
16
- def deep_clone
17
- new_obj = clone
18
-
19
- new_obj.attributes = new_obj.attributes.dup
20
-
21
- new_obj
22
- end
23
-
24
- tag_method(:delete) do
25
- destructive!
26
- end
27
- def delete(*args)
28
- super
29
-
30
- value_updated
31
- end
32
-
33
- def method_missing(method_name, *args, &block)
34
- result = super
35
-
36
- if method_name[0] == '_' && method_name[-1] == '='
37
- # Trigger value updated after an assignment
38
- self.value_updated
39
- end
40
-
41
- return result
42
- end
43
-
44
- def value_updated
45
- # Once the initial url has been parsed and set into the attributes,
46
- # start triggering updates on change events.
47
- # TODO: This is a temp solution, we need to make it so value_updated
48
- # is called after the reactive_value has been updated.
49
- if RUBY_PLATFORM == 'opal'
50
- %x{
51
- if (window.setTimeout && this.$run_update.bind) {
52
- if (window.paramsUpdateTimer) {
53
- clearTimeout(window.paramsUpdateTimer);
54
- }
55
- window.paramsUpdateTimer = setTimeout(this.$run_update.bind(this), 0);
56
- }
57
- }
58
- end
59
- end
60
-
61
- def run_update
62
- $page.params.trigger!('child_changed') if Volt.client?
63
- end
64
-
65
- def new_model(*args)
66
- Params.new(*args)
67
- end
68
-
69
- def new_array_model(*args)
70
- ParamsArray.new(*args)
71
- end
72
- end
@@ -1,9 +0,0 @@
1
- class ParamsArray < ArrayModel
2
- def new_model(*args)
3
- Params.new(*args)
4
- end
5
-
6
- def new_array_model(*args)
7
- ParamsArray.new(*args)
8
- end
9
- end
@@ -1,183 +0,0 @@
1
- require 'volt/models/store_array'
2
-
3
- class Store < Model
4
- ID_CHARS = [('a'..'z'), ('A'..'Z'), ('0'..'9')].map {|v| v.to_a }.flatten
5
-
6
- @@identity_map = {}
7
-
8
- attr_reader :state
9
-
10
- def initialize(tasks=nil, *args)
11
- @tasks = tasks
12
- @state = :not_loaded
13
-
14
- super(*args)
15
-
16
- track_in_identity_map if attributes && attributes[:_id]
17
-
18
- value_updated
19
- end
20
-
21
- def self.from_id(id)
22
- @@identity_map[id]
23
- end
24
-
25
- def event_added(event, scope_provider, first)
26
- if first && event == :changed
27
- # Start listening
28
- ensure_id
29
- change_channel_connection("add")
30
- end
31
- end
32
-
33
- def event_removed(event, no_more_events)
34
- if no_more_events && event == :changed
35
- # Stop listening
36
- change_channel_connection("remove")
37
- end
38
- end
39
-
40
- def change_channel_connection(add_or_remove)
41
- if attributes && path.size > 1
42
- channel_name = "#{path[-2]}##{attributes[:_id]}"
43
- puts "Event Added: #{channel_name} -- #{attributes.inspect}"
44
- @tasks.call('ChannelTasks', "#{add_or_remove}_listener", channel_name)
45
- end
46
- end
47
-
48
- def self.update(model_id, data)
49
- model = @@identity_map[model_id]
50
-
51
- if model
52
- data.each_pair do |key, value|
53
- if key != '_id'
54
- model.send(:"#{key}=", value)
55
- end
56
- end
57
- end
58
- end
59
-
60
- def generate_id
61
- id = []
62
- 12.times { id << ID_CHARS.sample }
63
-
64
- return id.join
65
- end
66
-
67
- def method_missing(method_name, *args, &block)
68
- if method_name[-1] == ']'
69
- # Load the model
70
- self.load!
71
- end
72
-
73
- result = super
74
-
75
- if method_name[0] == '_' && method_name[-1] == '='
76
- # Trigger value updated after an assignment
77
- self.value_updated
78
- end
79
-
80
- return result
81
- end
82
-
83
- def track_in_identity_map
84
- @@identity_map[attributes[:_id]] = self
85
- end
86
-
87
- # When called, will setup an id if there is not one
88
- def ensure_id
89
- # No id yet, lets create one
90
- if attributes && !attributes[:_id]
91
- self.attributes[:_id] = generate_id
92
- track_in_identity_map
93
- end
94
- end
95
-
96
- def value_updated
97
- path_size = path.size
98
- if !(defined?($loading_models) && $loading_models) && @tasks && path_size > 0 && !nil?
99
-
100
- ensure_id
101
-
102
- if path_size > 3 && parent && source = parent.parent
103
- self.attributes[:"#{path[-4].singularize}_id"] = source._id
104
- end
105
-
106
- # puts "Save: #{collection} - #{attrs.inspect}"
107
- @tasks.call('StoreTasks', 'save', collection, self_attributes)
108
- end
109
- end
110
-
111
- # Return the attributes that are only for this store, not any sub-associations.
112
- def self_attributes
113
- # Don't store any sub-stores, those will do their own saving.
114
- attrs = attributes.reject {|k,v| v.is_a?(Model) || v.is_a?(ArrayModel) }
115
- end
116
-
117
- def collection(path=nil)
118
- path ||= self.path
119
-
120
- collection_name = path.last
121
- collection_name = path[-2] if collection_name == :[]
122
-
123
- return collection_name
124
- end
125
-
126
- # On stores, we store the model so we don't have to look it up
127
- # every time we do a read.
128
- def read_new_model(method_name)
129
- # On stores, plural associations are automatically assumed to be
130
- # collections.
131
- if method_name.plural?
132
- model = new_array_model([], self, path + [method_name])
133
- else
134
- model = new_model(nil, self, path + [method_name])
135
- end
136
-
137
- self.attributes ||= {}
138
- attributes[method_name] = model
139
-
140
- if model.is_a?(StoreArray)# && model.state == :not_loaded
141
- model.load!
142
- end
143
-
144
- return model
145
- end
146
-
147
-
148
- # When called, this model is deleted from its current parent collection
149
- # and from the database
150
- def delete!
151
- if path.size == 0
152
- raise "Not in a collection"
153
- end
154
-
155
- # TEMP: Find this model in the parent's collection
156
- parent.each_with_index do |child,index|
157
- puts "CHECK #{child.inspect} vs #{self.inspect}"
158
- if child._id == self._id
159
- puts "FOUND AT: #{index}"
160
- parent.delete_at(index)
161
- break
162
- end
163
- end
164
-
165
- # Send to the DB that we got deleted
166
- unless $loading_models
167
- puts "delete #{collection} - #{attributes[:_id]}"
168
- @tasks.call('StoreTasks', 'delete', collection, attributes[:_id])
169
- end
170
- end
171
-
172
- def inspect
173
- "<#{self.class.to_s}-#{@state} #{attributes.inspect}>"
174
- end
175
-
176
- def new_model(attributes={}, parent=nil, path=nil, class_paths=nil)
177
- return Store.new(@tasks, attributes, parent, path, class_paths)
178
- end
179
-
180
- def new_array_model(*args)
181
- StoreArray.new(@tasks, *args)
182
- end
183
- end
@@ -1,82 +0,0 @@
1
- class StoreArray < ArrayModel
2
- attr_reader :state
3
-
4
- def initialize(tasks=nil, array=[], parent=nil, path=nil)
5
- @tasks = tasks
6
- @state = :not_loaded
7
-
8
- super(array, parent, path)
9
-
10
- # TEMP: TODO: Setup the listeners right away
11
- change_channel_connection('add', 'added')
12
- change_channel_connection('add', 'removed')
13
- end
14
-
15
- # def event_added(event, scope_provider, first)
16
- # puts "New event1: #{event.inspect} - #{first}"
17
- # if first && [:added, :removed].include?(event)
18
- # # Start listening for added items on the collection
19
- #
20
- # change_channel_connection('add', event)
21
- # end
22
- # end
23
- #
24
- # def event_removed(event, no_more_events)
25
- # if no_more_events && [:added, :removed].include?(event)
26
- # # Stop listening
27
- # change_channel_connection("remove", event)
28
- # end
29
- # end
30
-
31
-
32
- def load!
33
- if @state == :not_loaded
34
- @state = :loading
35
-
36
- if @tasks && path.last.plural?
37
- # Check to see the parents scope so we can only lookup associated
38
- # models.
39
- scope = {}
40
-
41
- # Scope to the parent
42
- if path.size > 1 && attributes && attributes[:_id].true?
43
- scope[:"#{path[-2].singularize}_id"] = _id
44
- end
45
-
46
- puts "Load At Scope: #{scope.inspect}"
47
-
48
- load_child_models(scope)
49
- end
50
- end
51
-
52
- return self
53
- end
54
-
55
- def load_child_models(scope)
56
- # puts "FIND: #{collection(path).inspect} at #{scope.inspect}"
57
- @tasks.call('StoreTasks', 'find', path.last, scope) do |results|
58
- # TODO: Globals evil, replace
59
- $loading_models = true
60
- results.each do |result|
61
- self << Store.new(@tasks, result, self, path + [:[]], @class_paths)
62
- end
63
- $loading_models = false
64
- end
65
- end
66
-
67
- def change_channel_connection(add_or_remove, event)
68
- if @tasks && parent.attributes && path.size != 0
69
- channel_name = "#{path[-1]}-#{event}"
70
- puts "Listen on #{channel_name} - #{add_or_remove}"
71
- @tasks.call('ChannelTasks', "#{add_or_remove}_listener", channel_name)
72
- end
73
- end
74
-
75
- def new_model(*args)
76
- Store.new(@tasks, *args)
77
- end
78
-
79
- def new_array_model(*args)
80
- StoreArray.new(@tasks, *args)
81
- end
82
- end
@@ -1,16 +0,0 @@
1
- require 'volt/models'
2
-
3
- describe Params do
4
- it "should stay as params classes when used" do
5
- a = Params.new
6
- expect(a._test.class).to eq(Params)
7
-
8
- expect(a._test._cool.class).to eq(Params)
9
-
10
- a._items << {_name: 'Test'}
11
-
12
- expect(a._items.class).to eq(ParamsArray)
13
- expect(a._items[0].class).to eq(Params)
14
- expect(a._items[0]._name.class).to eq(String)
15
- end
16
- end