volt 0.7.23 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|