volt 0.7.23 → 0.8.0
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 +4 -4
- data/.travis.yml +8 -1
- data/CHANGELOG.md +22 -0
- data/Gemfile +8 -0
- data/Guardfile +2 -2
- data/Readme.md +139 -136
- data/VERSION +1 -1
- data/app/volt/assets/js/setImmediate.js +175 -0
- data/app/volt/tasks/live_query/data_store.rb +0 -2
- data/app/volt/tasks/live_query/live_query.rb +4 -4
- data/docs/GETTING_STARTED.md +24 -3
- data/docs/WHY.md +1 -22
- data/lib/volt.rb +20 -1
- data/lib/volt/console.rb +20 -0
- data/lib/volt/controllers/model_controller.rb +25 -11
- data/lib/volt/extra_core/object.rb +2 -14
- data/lib/volt/extra_core/string.rb +4 -0
- data/lib/volt/models.rb +0 -1
- data/lib/volt/models/array_model.rb +8 -16
- data/lib/volt/models/cursor.rb +1 -1
- data/lib/volt/models/model.rb +40 -60
- data/lib/volt/models/model_hash_behaviour.rb +10 -24
- data/lib/volt/models/model_helpers.rb +2 -2
- data/lib/volt/models/model_state.rb +1 -1
- data/lib/volt/models/model_wrapper.rb +4 -4
- data/lib/volt/models/persistors/array_store.rb +44 -28
- data/lib/volt/models/persistors/base.rb +1 -1
- data/lib/volt/models/persistors/model_store.rb +1 -1
- data/lib/volt/models/persistors/params.rb +5 -1
- data/lib/volt/models/persistors/query/query_listener.rb +2 -0
- data/lib/volt/models/persistors/store.rb +3 -2
- data/lib/volt/models/persistors/store_state.rb +7 -2
- data/lib/volt/models/url.rb +35 -29
- data/lib/volt/models/validations.rb +7 -17
- data/lib/volt/page/bindings/attribute_binding.rb +57 -39
- data/lib/volt/page/bindings/base_binding.rb +0 -14
- data/lib/volt/page/bindings/content_binding.rb +15 -18
- data/lib/volt/page/bindings/each_binding.rb +67 -34
- data/lib/volt/page/bindings/if_binding.rb +15 -12
- data/lib/volt/page/bindings/template_binding.rb +77 -59
- data/lib/volt/page/bindings/template_binding/grouped_controllers.rb +19 -4
- data/lib/volt/page/channel.rb +22 -38
- data/lib/volt/page/channel_stub.rb +3 -6
- data/lib/volt/page/page.rb +24 -26
- data/lib/volt/page/string_template_renderer.rb +46 -0
- data/lib/volt/page/sub_context.rb +7 -1
- data/lib/volt/page/targets/binding_document/component_node.rb +11 -9
- data/lib/volt/page/tasks.rb +3 -2
- data/lib/volt/page/url_tracker.rb +4 -3
- data/lib/volt/reactive/computation.rb +131 -0
- data/lib/volt/reactive/dependency.rb +71 -0
- data/lib/volt/reactive/eventable.rb +82 -0
- data/lib/volt/reactive/hash_dependency.rb +36 -0
- data/lib/volt/{controllers → reactive}/reactive_accessors.rb +8 -11
- data/lib/volt/reactive/reactive_array.rb +100 -193
- data/lib/volt/reactive/reactive_hash.rb +49 -0
- data/lib/volt/server/html_parser/attribute_scope.rb +24 -4
- data/lib/volt/server/html_parser/if_view_scope.rb +15 -15
- data/lib/volt/server/html_parser/view_scope.rb +31 -1
- data/spec/apps/kitchen_sink/Gemfile +4 -8
- data/spec/apps/kitchen_sink/app/main/config/dependencies.rb +8 -0
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +8 -1
- data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +8 -0
- data/spec/apps/kitchen_sink/app/main/views/main/bindings.html +73 -0
- data/spec/apps/kitchen_sink/app/main/views/main/index.html +6 -1
- data/spec/apps/kitchen_sink/app/main/views/main/main.html +26 -6
- data/spec/apps/kitchen_sink/app/main/views/main/store.html +6 -0
- data/spec/controllers/reactive_accessors_spec.rb +13 -15
- data/spec/integration/bindings_spec.rb +159 -0
- data/spec/integration/templates_spec.rb +15 -0
- data/spec/models/model_spec.rb +130 -228
- data/spec/reactive/computation_spec.rb +63 -0
- data/spec/reactive/dependency_spec.rb +5 -0
- data/spec/reactive/eventable_spec.rb +48 -0
- data/spec/reactive/reactive_array_spec.rb +97 -0
- data/spec/router/routes_spec.rb +26 -27
- data/spec/server/html_parser/view_parser_spec.rb +3 -21
- data/spec/server/rack/asset_files_spec.rb +1 -1
- data/templates/project/app/main/views/main/main.html +2 -2
- metadata +29 -41
- data/lib/volt/extra_core/time.rb +0 -16
- data/lib/volt/page/draw_cycle.rb +0 -31
- data/lib/volt/page/memory_test.rb +0 -26
- data/lib/volt/page/reactive_template.rb +0 -32
- data/lib/volt/reactive/array_extensions.rb +0 -12
- data/lib/volt/reactive/destructive_methods.rb +0 -19
- data/lib/volt/reactive/event_chain.rb +0 -125
- data/lib/volt/reactive/events.rb +0 -216
- data/lib/volt/reactive/object_tracking.rb +0 -14
- data/lib/volt/reactive/reactive_block.rb +0 -88
- data/lib/volt/reactive/reactive_generator.rb +0 -44
- data/lib/volt/reactive/reactive_tags.rb +0 -71
- data/lib/volt/reactive/reactive_value.rb +0 -427
- data/lib/volt/reactive/string_extensions.rb +0 -31
- data/spec/integration/test_integration_spec.rb +0 -14
- data/spec/models/event_chain_spec.rb +0 -150
- data/spec/models/model_buffers_spec.rb +0 -9
- data/spec/models/old_model_spec.rb +0 -67
- data/spec/models/reactive_array_spec.rb +0 -364
- data/spec/models/reactive_block_spec.rb +0 -13
- data/spec/models/reactive_call_times_spec.rb +0 -28
- data/spec/models/reactive_generator_spec.rb +0 -58
- data/spec/models/reactive_tags_spec.rb +0 -35
- data/spec/models/reactive_value_spec.rb +0 -370
- data/spec/models/store_spec.rb +0 -16
- data/spec/models/string_extensions_spec.rb +0 -57
data/lib/volt/models.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'volt/reactive/reactive_array'
|
|
1
2
|
require 'volt/models/model_wrapper'
|
|
2
3
|
require 'volt/models/model_helpers'
|
|
3
4
|
require 'volt/models/model_state'
|
|
@@ -36,21 +37,14 @@ class ArrayModel < ReactiveArray
|
|
|
36
37
|
@persistor.loaded if @persistor
|
|
37
38
|
end
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
destructive!
|
|
41
|
-
pass_reactive!
|
|
42
|
-
end
|
|
43
|
-
def find(*args)
|
|
40
|
+
def find(*args, &block)
|
|
44
41
|
if @persistor
|
|
45
|
-
return @persistor.find(*args)
|
|
42
|
+
return @persistor.find(*args, &block)
|
|
46
43
|
else
|
|
47
44
|
raise "this model's persistance layer does not support find, try using store"
|
|
48
45
|
end
|
|
49
46
|
end
|
|
50
47
|
|
|
51
|
-
tag_method(:then) do
|
|
52
|
-
destructive!
|
|
53
|
-
end
|
|
54
48
|
def then(*args, &block)
|
|
55
49
|
if @persistor
|
|
56
50
|
return @persistor.then(*args, &block)
|
|
@@ -65,9 +59,10 @@ class ArrayModel < ReactiveArray
|
|
|
65
59
|
|
|
66
60
|
# Make sure it gets wrapped
|
|
67
61
|
def <<(model)
|
|
68
|
-
|
|
62
|
+
# TODORW: handle changes
|
|
63
|
+
if model.is_a?(Model)
|
|
69
64
|
# Set the new path
|
|
70
|
-
model.
|
|
65
|
+
model.options = @options.merge(path: @options[:path] + [:[]])
|
|
71
66
|
else
|
|
72
67
|
model = wrap_values([model]).first
|
|
73
68
|
end
|
|
@@ -117,12 +112,9 @@ class ArrayModel < ReactiveArray
|
|
|
117
112
|
end
|
|
118
113
|
|
|
119
114
|
# Otherwise inspect normally
|
|
120
|
-
super
|
|
115
|
+
return super
|
|
121
116
|
end
|
|
122
117
|
|
|
123
|
-
tag_method(:buffer) do
|
|
124
|
-
destructive!
|
|
125
|
-
end
|
|
126
118
|
def buffer
|
|
127
119
|
model_path = options[:path] + [:[]]
|
|
128
120
|
model_klass = class_at_path(model_path)
|
|
@@ -130,7 +122,7 @@ class ArrayModel < ReactiveArray
|
|
|
130
122
|
new_options = options.merge(path: model_path, save_to: self).reject {|k,_| k.to_sym == :persistor }
|
|
131
123
|
model = model_klass.new({}, new_options)
|
|
132
124
|
|
|
133
|
-
return
|
|
125
|
+
return model
|
|
134
126
|
end
|
|
135
127
|
|
|
136
128
|
private
|
data/lib/volt/models/cursor.rb
CHANGED
data/lib/volt/models/model.rb
CHANGED
|
@@ -1,42 +1,34 @@
|
|
|
1
1
|
require 'volt/models/model_wrapper'
|
|
2
2
|
require 'volt/models/array_model'
|
|
3
3
|
require 'volt/models/model_helpers'
|
|
4
|
-
require 'volt/reactive/object_tracking'
|
|
5
4
|
require 'volt/models/model_hash_behaviour'
|
|
6
5
|
require 'volt/models/validations'
|
|
7
6
|
require 'volt/models/model_state'
|
|
8
|
-
|
|
7
|
+
require 'volt/reactive/reactive_hash'
|
|
9
8
|
|
|
10
9
|
class NilMethodCall < NoMethodError
|
|
11
|
-
def true?
|
|
12
|
-
false
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def false?
|
|
16
|
-
true
|
|
17
|
-
end
|
|
18
10
|
end
|
|
19
11
|
|
|
12
|
+
|
|
20
13
|
class Model
|
|
21
|
-
include ReactiveTags
|
|
22
14
|
include ModelWrapper
|
|
23
|
-
include ObjectTracking
|
|
24
15
|
include ModelHelpers
|
|
25
16
|
include ModelHashBehaviour
|
|
26
17
|
include Validations
|
|
27
18
|
include ModelState
|
|
28
19
|
|
|
29
|
-
|
|
20
|
+
attr_reader :attributes
|
|
30
21
|
attr_reader :parent, :path, :persistor, :options
|
|
31
22
|
|
|
32
23
|
def initialize(attributes={}, options={}, initial_state=nil)
|
|
24
|
+
@deps = HashDependency.new
|
|
33
25
|
self.options = options
|
|
34
26
|
|
|
35
27
|
self.send(:attributes=, attributes, true)
|
|
36
28
|
|
|
37
29
|
@cache = {}
|
|
38
30
|
|
|
39
|
-
# Models
|
|
31
|
+
# Models start in a loaded state since they are normally setup from an
|
|
40
32
|
# ArrayModel, which will have the data when they get added.
|
|
41
33
|
@state = :loaded
|
|
42
34
|
|
|
@@ -56,8 +48,11 @@ class Model
|
|
|
56
48
|
def attributes=(attrs, initial_setup=false)
|
|
57
49
|
@attributes = wrap_values(attrs)
|
|
58
50
|
|
|
51
|
+
# Trigger and change all
|
|
52
|
+
@deps.changed_all!
|
|
53
|
+
@deps = HashDependency.new
|
|
54
|
+
|
|
59
55
|
unless initial_setup
|
|
60
|
-
trigger!('changed')
|
|
61
56
|
|
|
62
57
|
# Let the persistor know something changed
|
|
63
58
|
if @persistor
|
|
@@ -86,11 +81,6 @@ class Model
|
|
|
86
81
|
end
|
|
87
82
|
|
|
88
83
|
|
|
89
|
-
tag_all_methods do
|
|
90
|
-
pass_reactive! do |method_name|
|
|
91
|
-
method_name[0] == '_' && method_name[-1] == '='
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
84
|
def method_missing(method_name, *args, &block)
|
|
95
85
|
if method_name[0] == '_'
|
|
96
86
|
if method_name[-1] == '='
|
|
@@ -116,10 +106,9 @@ class Model
|
|
|
116
106
|
attribute_name = method_name[0..-2].to_sym
|
|
117
107
|
|
|
118
108
|
value = args[0]
|
|
119
|
-
__assign_element(attribute_name, value)
|
|
120
109
|
|
|
121
110
|
attributes[attribute_name] = wrap_value(value, [attribute_name])
|
|
122
|
-
|
|
111
|
+
@deps.changed!(attribute_name)
|
|
123
112
|
|
|
124
113
|
# Let the persistor know something changed
|
|
125
114
|
@persistor.changed(attribute_name) if @persistor
|
|
@@ -144,6 +133,9 @@ class Model
|
|
|
144
133
|
# Also check @cache
|
|
145
134
|
value ||= (@cache && @cache[method_name])
|
|
146
135
|
|
|
136
|
+
# Track dependency
|
|
137
|
+
@deps.depend(method_name)
|
|
138
|
+
|
|
147
139
|
if value
|
|
148
140
|
# key was in attributes or cache
|
|
149
141
|
return value
|
|
@@ -162,9 +154,14 @@ class Model
|
|
|
162
154
|
# Get a new model, make it easy to override
|
|
163
155
|
def read_new_model(method_name)
|
|
164
156
|
if @persistor && @persistor.respond_to?(:read_new_model)
|
|
165
|
-
@persistor.read_new_model(method_name)
|
|
157
|
+
return @persistor.read_new_model(method_name)
|
|
166
158
|
else
|
|
167
|
-
|
|
159
|
+
opts = @options.merge(parent: self, path: path + [method_name])
|
|
160
|
+
if method_name.plural?
|
|
161
|
+
return new_array_model([], opts)
|
|
162
|
+
else
|
|
163
|
+
return new_model(nil, opts)
|
|
164
|
+
end
|
|
168
165
|
end
|
|
169
166
|
end
|
|
170
167
|
|
|
@@ -225,9 +222,6 @@ class Model
|
|
|
225
222
|
end
|
|
226
223
|
end
|
|
227
224
|
|
|
228
|
-
tag_method(:<<) do
|
|
229
|
-
pass_reactive!
|
|
230
|
-
end
|
|
231
225
|
# Initialize an empty array and append to it
|
|
232
226
|
def <<(value)
|
|
233
227
|
if @parent
|
|
@@ -249,14 +243,20 @@ class Model
|
|
|
249
243
|
# Add the new item
|
|
250
244
|
result << value
|
|
251
245
|
|
|
252
|
-
|
|
253
|
-
trigger!('
|
|
246
|
+
# TODORW:
|
|
247
|
+
# trigger!('added', nil, 0)
|
|
248
|
+
# trigger!('changed')
|
|
254
249
|
|
|
255
250
|
return nil
|
|
256
251
|
end
|
|
257
252
|
|
|
258
253
|
def inspect
|
|
259
|
-
|
|
254
|
+
str = nil
|
|
255
|
+
Computation.run_without_tracking do
|
|
256
|
+
str = "<#{self.class.to_s}:#{object_id} #{attributes.inspect}>"
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
return str
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
def deep_cur
|
|
@@ -294,7 +294,6 @@ class Model
|
|
|
294
294
|
self.class.validations.keys.each do |key|
|
|
295
295
|
mark_field!(key.to_sym)
|
|
296
296
|
end
|
|
297
|
-
trigger_for_methods!('changed', :errors, :marked_errors)
|
|
298
297
|
|
|
299
298
|
return Promise.new.reject(errors)
|
|
300
299
|
end
|
|
@@ -302,12 +301,15 @@ class Model
|
|
|
302
301
|
|
|
303
302
|
|
|
304
303
|
# Returns a buffered version of the model
|
|
305
|
-
tag_method(:buffer) do
|
|
306
|
-
destructive!
|
|
307
|
-
end
|
|
308
304
|
def buffer
|
|
309
305
|
model_path = options[:path]
|
|
310
|
-
|
|
306
|
+
|
|
307
|
+
# When we grab a buffer off of a plual class (subcollection), we get it as a model.
|
|
308
|
+
if model_path.last.plural? && model_path[-1] != :[]
|
|
309
|
+
model_klass = class_at_path(model_path + [:[]])
|
|
310
|
+
else
|
|
311
|
+
model_klass = class_at_path(model_path)
|
|
312
|
+
end
|
|
311
313
|
|
|
312
314
|
new_options = options.merge(path: model_path, save_to: self).reject {|k,_| k.to_sym == :persistor }
|
|
313
315
|
model = model_klass.new({}, new_options, :loading)
|
|
@@ -320,36 +322,14 @@ class Model
|
|
|
320
322
|
end
|
|
321
323
|
end
|
|
322
324
|
|
|
323
|
-
return
|
|
325
|
+
return model
|
|
324
326
|
end
|
|
325
327
|
|
|
326
328
|
|
|
327
329
|
private
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
# Clear the previous value and assign a new one
|
|
334
|
-
def __assign_element(key, value)
|
|
335
|
-
__clear_element(key)
|
|
336
|
-
__track_element(key, value)
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
# TODO: Somewhat duplicated from ReactiveArray
|
|
340
|
-
def __clear_element(key)
|
|
341
|
-
# Cleanup any tracking on an index
|
|
342
|
-
# TODO: is this send a security risk?
|
|
343
|
-
if @reactive_element_listeners && @reactive_element_listeners[key]
|
|
344
|
-
@reactive_element_listeners[key].remove
|
|
345
|
-
@reactive_element_listeners.delete(key)
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
def __track_element(key, value)
|
|
350
|
-
__setup_tracking(key, value) do |event, key, args|
|
|
351
|
-
trigger_by_attribute!(event, key, *args)
|
|
352
|
-
end
|
|
330
|
+
def setup_buffer(model)
|
|
331
|
+
model.attributes = self.attributes
|
|
332
|
+
model.change_state_to(:loaded)
|
|
353
333
|
end
|
|
354
334
|
|
|
355
335
|
# Takes the persistor if there is one and
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
# Moving this into a module cleans up the main Model class for things that
|
|
3
3
|
# make it behave like a model.
|
|
4
4
|
module ModelHashBehaviour
|
|
5
|
-
def self.included(base)
|
|
6
|
-
# In modules, since we need to tag on the main class, we setup the
|
|
7
|
-
# tags with included.
|
|
8
|
-
base.tag_method(:delete) do
|
|
9
|
-
destructive!
|
|
10
|
-
end
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
end
|
|
6
|
+
def delete(name)
|
|
7
|
+
name = name.to_sym
|
|
16
8
|
|
|
9
|
+
value = attributes.delete(name)
|
|
10
|
+
@deps.delete(name)
|
|
11
|
+
|
|
12
|
+
@persistor.removed(name) if @persistor
|
|
13
|
+
|
|
14
|
+
return value
|
|
15
|
+
end
|
|
17
16
|
|
|
18
17
|
def nil?
|
|
19
18
|
attributes.nil?
|
|
@@ -27,25 +26,12 @@ module ModelHashBehaviour
|
|
|
27
26
|
attributes.true?
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
def delete(name)
|
|
31
|
-
name = name.to_sym
|
|
32
|
-
__clear_element(name)
|
|
33
|
-
value = attributes.delete(name)
|
|
34
|
-
trigger_by_attribute!('changed', name)
|
|
35
|
-
|
|
36
|
-
@persistor.removed(name) if @persistor
|
|
37
|
-
|
|
38
|
-
return value
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
|
|
42
29
|
def clear
|
|
43
30
|
attributes.each_pair do |key,value|
|
|
44
|
-
|
|
31
|
+
@deps.changed!(key)
|
|
45
32
|
end
|
|
46
33
|
|
|
47
34
|
attributes.clear
|
|
48
|
-
trigger!('changed')
|
|
49
35
|
|
|
50
36
|
@persistor.removed(nil) if @persistor
|
|
51
37
|
end
|
|
@@ -12,8 +12,8 @@ module ModelHelpers
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Pass to the persisotr
|
|
15
|
-
def event_added(event,
|
|
16
|
-
@persistor.event_added(event,
|
|
15
|
+
def event_added(event, first, first_for_event)
|
|
16
|
+
@persistor.event_added(event, first, first_for_event) if @persistor
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# Pass to the persistor
|
|
@@ -2,9 +2,9 @@ module ModelWrapper
|
|
|
2
2
|
# For cretain values, we wrap them to make the behave as a
|
|
3
3
|
# model.
|
|
4
4
|
def wrap_value(value, lookup)
|
|
5
|
-
if value.
|
|
5
|
+
if value.is_a?(Array)
|
|
6
6
|
value = new_array_model(value, @options.merge(parent: self, path: path + lookup))
|
|
7
|
-
elsif value.
|
|
7
|
+
elsif value.is_a?(Hash)
|
|
8
8
|
value = new_model(value, @options.merge(parent: self, path: path + lookup))
|
|
9
9
|
end
|
|
10
10
|
|
|
@@ -12,10 +12,10 @@ module ModelWrapper
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def wrap_values(values, lookup=[])
|
|
15
|
-
if values.
|
|
15
|
+
if values.is_a?(Array)
|
|
16
16
|
# Coming from an array
|
|
17
17
|
values = values.map {|v| wrap_value(v,lookup + [:[]]) }
|
|
18
|
-
elsif values.
|
|
18
|
+
elsif values.is_a?(Hash)
|
|
19
19
|
pairs = values.map do |k,v|
|
|
20
20
|
path = lookup + [k]
|
|
21
21
|
|
|
@@ -17,28 +17,32 @@ module Persistors
|
|
|
17
17
|
def initialize(model, tasks=nil)
|
|
18
18
|
super
|
|
19
19
|
|
|
20
|
-
query = @model.options[:query]
|
|
21
|
-
|
|
22
|
-
@query = ReactiveValue.from_hash(query || {})
|
|
20
|
+
@query = @model.options[:query]
|
|
23
21
|
end
|
|
24
22
|
|
|
25
|
-
def event_added(event,
|
|
23
|
+
def event_added(event, first, first_for_event)
|
|
26
24
|
# First event, we load the data.
|
|
27
|
-
|
|
25
|
+
if first
|
|
26
|
+
@has_events = true
|
|
27
|
+
load_data
|
|
28
|
+
end
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def event_removed(event, last, last_for_event)
|
|
31
32
|
# Remove listener where there are no more events on this model
|
|
32
|
-
|
|
33
|
+
if last
|
|
34
|
+
@has_events = false
|
|
35
|
+
stop_listening
|
|
36
|
+
end
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
# Called when an event is removed and we no longer want to keep in
|
|
36
40
|
# sync with the database.
|
|
37
|
-
def stop_listening
|
|
38
|
-
if @
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
def stop_listening(stop_watching_query=true)
|
|
42
|
+
return if @has_events
|
|
43
|
+
return if @fetch_promises && @fetch_promises.size > 0
|
|
44
|
+
|
|
45
|
+
@query_computation.stop if @query_computation && stop_watching_query
|
|
42
46
|
|
|
43
47
|
if @query_listener
|
|
44
48
|
@query_listener.remove_store(self)
|
|
@@ -52,22 +56,21 @@ module Persistors
|
|
|
52
56
|
def load_data
|
|
53
57
|
# Don't load data from any queried
|
|
54
58
|
if @state == :not_loaded || @state == :dirty
|
|
55
|
-
# puts "Load Data at #{@model.path.inspect} - query: #{@query.inspect}
|
|
59
|
+
# puts "Load Data at #{@model.path.inspect} - query: #{@query.inspect} on #{self.inspect}"
|
|
56
60
|
change_state_to :loading
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@query_changed_listener = @query.on('changed') do
|
|
63
|
-
stop_listening
|
|
62
|
+
if @query.is_a?(Proc)
|
|
63
|
+
@query_computation = -> do
|
|
64
|
+
puts "Run Query Again"
|
|
65
|
+
stop_listening(false)
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
load_data if @model.has_listeners?
|
|
67
|
-
end
|
|
68
|
-
end
|
|
67
|
+
change_state_to :loading
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
run_query(@model, @query.call)
|
|
70
|
+
end.watch!
|
|
71
|
+
else
|
|
72
|
+
run_query(@model, @query)
|
|
73
|
+
end
|
|
71
74
|
end
|
|
72
75
|
end
|
|
73
76
|
|
|
@@ -78,6 +81,9 @@ module Persistors
|
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
def run_query(model, query={})
|
|
84
|
+
@model.clear
|
|
85
|
+
|
|
86
|
+
# puts "Run Query: #{query.inspect}"
|
|
81
87
|
collection = model.path.last
|
|
82
88
|
# Scope to the parent
|
|
83
89
|
if model.path.size > 1
|
|
@@ -98,10 +104,20 @@ module Persistors
|
|
|
98
104
|
@query_listener.add_store(self)
|
|
99
105
|
end
|
|
100
106
|
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
# Find can take either a query object, or a block that returns a query object. Use
|
|
108
|
+
# the block style if you need reactive updating queries
|
|
109
|
+
def find(query=nil, &block)
|
|
110
|
+
# Set a default query if there is no block
|
|
111
|
+
if block
|
|
112
|
+
if query
|
|
113
|
+
raise "Query should not be passed in to a find if a block is specified"
|
|
114
|
+
end
|
|
115
|
+
query = block
|
|
116
|
+
else
|
|
117
|
+
query ||= {}
|
|
118
|
+
end
|
|
103
119
|
|
|
104
|
-
return
|
|
120
|
+
return Cursor.new([], @model.options.merge(:query => query))
|
|
105
121
|
end
|
|
106
122
|
|
|
107
123
|
# Returns a promise that is resolved/rejected when the query is complete. Any
|
|
@@ -130,7 +146,7 @@ module Persistors
|
|
|
130
146
|
new_options = @model.options.merge(path: @model.path + [:[]], parent: @model)
|
|
131
147
|
|
|
132
148
|
# Don't add if the model is already in the ArrayModel
|
|
133
|
-
if !@model.
|
|
149
|
+
if !@model.array.find {|v| v['_id'] == data['_id'] }
|
|
134
150
|
# Find the existing model, or create one
|
|
135
151
|
new_model = @@identity_map.find(data['_id']) { @model.new_model(data.symbolize_keys, new_options, :loaded) }
|
|
136
152
|
|
|
@@ -159,9 +175,9 @@ module Persistors
|
|
|
159
175
|
@model.path[-1]
|
|
160
176
|
end
|
|
161
177
|
|
|
162
|
-
|
|
163
178
|
# When a model is added to this collection, we call its "changed"
|
|
164
179
|
# method. This should trigger a save.
|
|
180
|
+
# TODORW:
|
|
165
181
|
def added(model, index)
|
|
166
182
|
if model.persistor
|
|
167
183
|
# Tell the persistor it was added
|