volt 0.4.9 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ require 'volt/models/persistors/base'
2
+
3
+ module Persistors
4
+ class Params < Base
5
+ def initialize(model)
6
+ @model = model
7
+ end
8
+
9
+ def changed(attribute_name)
10
+ if RUBY_PLATFORM == 'opal'
11
+ %x{
12
+ if (window.setTimeout && this.$run_update.bind) {
13
+ if (window.paramsUpdateTimer) {
14
+ clearTimeout(window.paramsUpdateTimer);
15
+ }
16
+ window.paramsUpdateTimer = setTimeout(this.$run_update.bind(this), 0);
17
+ }
18
+ }
19
+ end
20
+ end
21
+
22
+ def run_update
23
+ $page.params.trigger!('child_changed') if Volt.client?
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require 'volt/models/persistors/base'
2
+
3
+ module Persistors
4
+ class Store < Base
5
+ def initialize(model, tasks=nil)
6
+ @model = model
7
+ @is_tracking = false
8
+ @tasks = tasks
9
+ end
10
+
11
+ def change_channel_connection(add_or_remove, event=nil, scope=nil)
12
+ if (@model.attributes && @model.path.size > 1) || @model.is_a?(ArrayModel)
13
+ channel_name = self.channel_name.to_s
14
+ channel_name += "-#{event}" if event
15
+
16
+ puts "Event #{add_or_remove}: #{channel_name} -- #{@model.attributes.inspect}"
17
+ @tasks.call('ChannelTasks', "#{add_or_remove}_listener", channel_name, scope)
18
+ end
19
+ end
20
+
21
+
22
+ # On stores, we store the model so we don't have to look it up
23
+ # every time we do a read.
24
+ def read_new_model(method_name)
25
+ # On stores, plural associations are automatically assumed to be
26
+ # collections.
27
+ options = @model.options.merge(parent: @model, path: @model.path + [method_name])
28
+ if method_name.plural?
29
+ model = @model.new_array_model([], options)
30
+ else
31
+ model = @model.new_model(nil, options)
32
+ end
33
+
34
+ @model.attributes ||= {}
35
+ @model.attributes[method_name] = model
36
+
37
+ # if model.is_a?(StoreArray)# && model.state == :not_loaded
38
+ # model.load!
39
+ # end
40
+
41
+ return model
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,15 @@
1
+ module Persistors
2
+ class StoreFactory
3
+ def initialize(tasks)
4
+ @tasks = tasks
5
+ end
6
+
7
+ def new(model)
8
+ if model.is_a?(ArrayModel)
9
+ ArrayStore.new(model, @tasks)
10
+ else
11
+ ModelStore.new(model, @tasks)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,7 +8,8 @@ class URL
8
8
 
9
9
  def initialize(router=nil)
10
10
  @router = router
11
- @params = Params.new({}, 'params')
11
+ @params = Model.new({}, persistor: Persistors::Params)
12
+ #Params.new({}, 'params')
12
13
  end
13
14
 
14
15
  # Parse takes in a url and extracts each sections.
@@ -17,8 +17,8 @@ class EachBinding < BaseBinding
17
17
  # Run the initial render
18
18
  update
19
19
 
20
- @added_listener = @value.on('added') { |_, position, item| puts "ADDED" ; item_added(position) }
21
- @changed_listener = @value.on('changed') { puts "CHANGED" ; reload }
20
+ @added_listener = @value.on('added') { |_, position, item| item_added(position) }
21
+ @changed_listener = @value.on('changed') { reload }
22
22
  @removed_listener = @value.on('removed') { |_, position| item_removed(position) }
23
23
  end
24
24
 
@@ -82,10 +82,8 @@ class Channel
82
82
  destructive!
83
83
  end
84
84
  def send_message(message)
85
- puts "Send #{message.inspect}"
86
85
  if @state != :open
87
86
  @queue << message
88
- puts "Queue"
89
87
  else
90
88
  # TODO: Temp: wrap message in an array, so we're sure its valid JSON
91
89
  message = JSON.dump([message])
@@ -4,7 +4,6 @@ if RUBY_PLATFORM == 'opal'
4
4
  require 'opal-jquery'
5
5
  end
6
6
  require 'volt/models'
7
- require 'volt/models/params'
8
7
  require 'volt/controllers/model_controller'
9
8
  require 'volt/page/bindings/attribute_binding'
10
9
  require 'volt/page/bindings/content_binding'
@@ -42,8 +41,8 @@ class Page
42
41
  @model_classes = {}
43
42
 
44
43
  # Run the code to setup the page
45
- @page = ReactiveValue.new(Model.new)#({}, nil, 'page', @model_classes))
46
- @store = ReactiveValue.new(Store.new(tasks))#({}, nil, 'store', @model_classes))
44
+ @page = ReactiveValue.new(Model.new)
45
+ @store = ReactiveValue.new(Model.new({}, persistor: Persistors::StoreFactory.new(tasks)))
47
46
 
48
47
  @url = ReactiveValue.new(URL.new)
49
48
  @params = @url.params
@@ -42,31 +42,52 @@ class Tasks
42
42
  end
43
43
  end
44
44
 
45
- def response(callback_id, *args)
45
+ def response(callback_id, result, error)
46
46
  callback = @callbacks.delete(callback_id)
47
47
 
48
48
  if callback
49
- callback.call(*args)
49
+ if error
50
+ # TODO: full error handling
51
+ puts "Error: #{error.inspect}"
52
+ else
53
+ callback.call(result)
54
+ end
50
55
  end
51
56
  end
52
57
 
53
58
  def changed(model_id, data)
54
59
  $loading_models = true
55
- puts "UPDATE: #{model_id} with #{data.inspect}"
56
- Store.update(model_id, data)
60
+ puts "From Backend: UPDATE: #{model_id} with #{data.inspect}"
61
+ Persistors::ModelStore.update(model_id, data)
57
62
  $loading_models = false
58
63
  end
59
64
 
60
65
  def added(path, data)
61
66
  $loading_models = true
62
- puts "Add: #{path.inspect} - #{data.inspect}"
63
- $page.store.send(path) << data
67
+
68
+ # Don't add if already in there
69
+ # TODO: shouldn't send twice
70
+ unless Persistors::ModelStore.from_id(data[:_id])
71
+
72
+ _, parent_id = data.find {|k,v| k != :_id && k[-3..-1] == '_id'}
73
+ if parent_id
74
+ parent_collection = Persistors::ModelStore.from_id(parent_id).model
75
+ else
76
+ # On the root
77
+ parent_collection = $page.store
78
+ end
79
+
80
+ puts "From Backend: Add: #{path.inspect} - #{data.inspect}"
81
+ parent_collection.send(path) << data
82
+ end
64
83
  $loading_models = false
65
84
  end
66
85
 
67
86
  def removed(id)
87
+ puts "From Backend: Remove: #{id}"
68
88
  $loading_models = true
69
- Store.from_id(id).delete!
89
+ model = Persistors::ModelStore.from_id(id)
90
+ model.delete!
70
91
  $loading_models = false
71
92
  end
72
93
 
@@ -53,7 +53,7 @@ class ReactiveArray# < Array
53
53
 
54
54
  __clear_element(index)
55
55
 
56
- @array.delete_at(index_val)
56
+ model = @array.delete_at(index_val)
57
57
 
58
58
  trigger_on_direct_listeners!('removed', index_val)
59
59
 
@@ -64,6 +64,19 @@ class ReactiveArray# < Array
64
64
  end
65
65
 
66
66
  trigger_size_change!
67
+
68
+ @persistor.removed(model) if @persistor
69
+
70
+ return model
71
+ end
72
+
73
+
74
+ # Delete is implemented as part of delete_at
75
+ tag_method(:delete) do
76
+ destructive!
77
+ end
78
+ def delete(val)
79
+ self.delete_at(@array.index(val))
67
80
  end
68
81
 
69
82
 
@@ -14,11 +14,17 @@ class Dispatcher
14
14
  klass = Object.send(:const_get, class_name)
15
15
 
16
16
  # Init and send the method
17
- result = klass.new(channel, self).send(method_name, *args)
17
+ begin
18
+ result = klass.new(channel, self).send(method_name, *args)
19
+ error = nil
20
+ rescue => e
21
+ result = nil
22
+ error = e
23
+ end
18
24
 
19
25
  if callback_id
20
26
  # Callback with result
21
- channel.send_message('response', callback_id, result)
27
+ channel.send_message('response', callback_id, result, error)
22
28
  end
23
29
  end
24
30
  end
@@ -293,7 +293,7 @@ describe Model do
293
293
 
294
294
  it "should handle a basic todo list with no setup" do
295
295
  store = ReactiveValue.new(Model.new)
296
- params = ReactiveValue.new(Params.new)
296
+ params = ReactiveValue.new(Model.new({}, persistor: Persistors::Params))
297
297
 
298
298
  a = store._todo_lists
299
299
  store._current_todo = store._todo_lists[params._index.or(0).to_i]
@@ -412,8 +412,30 @@ describe Model do
412
412
 
413
413
  end
414
414
 
415
- it "should set its self to be " do
415
+ it "should delete from an ArrayModel" do
416
+ array = ArrayModel.new([])
416
417
 
418
+ array << {_name: 'One'}
419
+ array << {_name: 'Two'}
420
+ array << {_name: 'Three'}
421
+
422
+ expect(array.size).to eq(3)
423
+
424
+ expect(array.index(array[0])).to eq(0)
425
+
426
+ array.delete(array[0])
427
+ expect(array.size).to eq(2)
428
+ expect(array[0]._name).to eq('Two')
429
+ end
430
+
431
+ it "should compare true" do
432
+ a = Model.new({_name: 'Cool'})
433
+ expect(a == a).to eq(true)
434
+ end
435
+
436
+ it "should do index" do
437
+ a = [{name: 'One'}, {name: 'Two'}, {name: 'Three'}]
438
+ expect(a.index(a[1])).to eq(1)
417
439
  end
418
440
 
419
441
 
@@ -438,4 +460,12 @@ describe Model do
438
460
  expect(@model._lists[0]._items.path.cur).to eq([:_lists, :[], :_items])
439
461
  end
440
462
  end
463
+
464
+ describe "persistors" do
465
+ it "should setup a new instance of the persistor with self" do
466
+ persistor = double('persistor')
467
+ expect(persistor).to receive(:new)
468
+ @model = Model.new(nil, persistor: persistor)
469
+ end
470
+ end
441
471
  end
@@ -0,0 +1,16 @@
1
+ require 'volt/models'
2
+
3
+ describe Persistors::Params do
4
+ it "should stay as params classes when used" do
5
+ a = Model.new({}, persistor: Persistors::Params)
6
+ expect(a._test.class).to eq(Model)
7
+
8
+ expect(a._test._cool.persistor.class).to eq(Persistors::Params)
9
+
10
+ a._items << {_name: 'Test'}
11
+
12
+ expect(a._items.persistor.class).to eq(Persistors::Params)
13
+ expect(a._items[0].persistor.class).to eq(Persistors::Params)
14
+ expect(a._items[0]._name.class).to eq(String)
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ require 'volt/models'
2
+
3
+ describe Persistors::Store do
4
+ it "should tell the persistor when the model has changed" do
5
+ persistor = double('persistor')
6
+ persistor_instance = double('persistor instance')
7
+ expect(persistor_instance).to receive(:loaded)
8
+ expect(persistor).to receive(:new).and_return(persistor_instance)
9
+
10
+ @model = Model.new(nil, persistor: persistor)
11
+
12
+ expect(persistor_instance).to receive(:changed)
13
+
14
+ @model._attr = 'yes'
15
+ end
16
+
17
+ it "should tell the persistor when something is added to an array model" do
18
+ persistor = double('persistor')
19
+ persistor_instance = double('persistor instance')
20
+ expect(persistor_instance).to receive(:loaded)
21
+ expect(persistor).to receive(:new).and_return(persistor_instance)
22
+
23
+ @model = ArrayModel.new([1,2,3], persistor: persistor)
24
+
25
+ expect(persistor_instance).to receive(:added).with(4)
26
+
27
+ @model << 4
28
+ end
29
+ end
@@ -1,16 +1,16 @@
1
- require 'volt/models'
2
-
3
- describe Store do
4
- it "should stay as store classes when used" do
5
- a = Store.new
6
- expect(a._test.class).to eq(Store)
7
-
8
- expect(a._test._cool.class).to eq(Store)
9
-
10
- a._items << {_name: 'Test'}
11
-
12
- expect(a._items.class).to eq(StoreArray)
13
- expect(a._items[0].class).to eq(Store)
14
- expect(a._items[0]._name.class).to eq(String)
15
- end
16
- end
1
+ # require 'volt/models'
2
+ #
3
+ # describe Store do
4
+ # # it "should stay as store classes when used" do
5
+ # # a = Store.new
6
+ # # expect(a._test.class).to eq(Store)
7
+ # #
8
+ # # expect(a._test._cool.class).to eq(Store)
9
+ # #
10
+ # # a._items << {_name: 'Test'}
11
+ # #
12
+ # # expect(a._items.class).to eq(StoreArray)
13
+ # # expect(a._items[0].class).to eq(Store)
14
+ # # expect(a._items[0]._name.class).to eq(String)
15
+ # # end
16
+ # end
@@ -8,7 +8,7 @@ end
8
8
 
9
9
  describe Routes do
10
10
  it "should match routes" do
11
- params = Params.new
11
+ params = Model.new({}, persistor: Persistors::Params)
12
12
  params._controller = 'blog'
13
13
  params._index = '5'
14
14
 
@@ -1,5 +1,6 @@
1
1
  class IndexController < ModelController
2
+ model :page
3
+
2
4
  def initialize
3
- @model = page
4
5
  end
5
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: volt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Stout
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-27 00:00:00.000000000 Z
11
+ date: 2014-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -354,10 +354,12 @@ files:
354
354
  - lib/volt/models/array_model.rb
355
355
  - lib/volt/models/model.rb
356
356
  - lib/volt/models/model_wrapper.rb
357
- - lib/volt/models/params.rb
358
- - lib/volt/models/params_array.rb
359
- - lib/volt/models/store.rb
360
- - lib/volt/models/store_array.rb
357
+ - lib/volt/models/persistors/array_store.rb
358
+ - lib/volt/models/persistors/base.rb
359
+ - lib/volt/models/persistors/model_store.rb
360
+ - lib/volt/models/persistors/params.rb
361
+ - lib/volt/models/persistors/store.rb
362
+ - lib/volt/models/persistors/store_factory.rb
361
363
  - lib/volt/models/url.rb
362
364
  - lib/volt/page/bindings/attribute_binding.rb
363
365
  - lib/volt/page/bindings/base_binding.rb
@@ -424,7 +426,8 @@ files:
424
426
  - spec/models/event_chain_spec.rb
425
427
  - spec/models/model_spec.rb
426
428
  - spec/models/old_model_spec.rb
427
- - spec/models/params_spec.rb
429
+ - spec/models/persistors/params_spec.rb
430
+ - spec/models/persistors/store_spec.rb
428
431
  - spec/models/reactive_array_spec.rb
429
432
  - spec/models/reactive_tags_spec.rb
430
433
  - spec/models/reactive_value_spec.rb
@@ -510,7 +513,8 @@ test_files:
510
513
  - spec/models/event_chain_spec.rb
511
514
  - spec/models/model_spec.rb
512
515
  - spec/models/old_model_spec.rb
513
- - spec/models/params_spec.rb
516
+ - spec/models/persistors/params_spec.rb
517
+ - spec/models/persistors/store_spec.rb
514
518
  - spec/models/reactive_array_spec.rb
515
519
  - spec/models/reactive_tags_spec.rb
516
520
  - spec/models/reactive_value_spec.rb