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.
@@ -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