opal-shimmer 0.1.2 → 0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0464c42ab04492cc79b6fb4c626c6e9a7307eed9
4
- data.tar.gz: 38d9ae5fe114dd33f1bde76bef21aefaf2bc96f7
3
+ metadata.gz: a1694f4e3a2e7065aa4b9fd21f3769dd112299ea
4
+ data.tar.gz: 769bb63b91b60ae4d167b8031376d5e40e71e0ce
5
5
  SHA512:
6
- metadata.gz: 9dbfb8a69b88e8ce27d461c749417d7c73caaa1f561a9a4f53a6d70b91971feb94ee079ecf3348039b2b8f696ce6f3cb4eb03b96524a7e9f1ae85f0d2cffcbc1
7
- data.tar.gz: fcc50acbc94b4f2a36de3e76909670c02a56467abacd16c1d0134e17aa974ed9ce7fd4243a07365e11b1047f76a9765ab6b1b66004d01fc4188745368c60f938
6
+ metadata.gz: 52ce8189f854edf7004589847e62b8ae47bfc094cf0b007707921b9779f5295bc85a7361692eec795aa18368f4dd5219e011d0cd64f32a22fed4f8b4586c57f8
7
+ data.tar.gz: b7023a2ff7b7f6073bfa8b900b706a52b4e8359caf7345b282d7a29317f14cc4dbd238db025e717c8c1f1694775659691041490c64df870a76ea347178495057
data/README.md CHANGED
@@ -20,52 +20,93 @@ Or install it yourself as:
20
20
 
21
21
  Shimmer is very easy to use right out of the box. I'm assuming you'll be using it within the context of a Rails application for this tutorial. Make sure you add `//= require shimmer` to your application.js manifest file.
22
22
 
23
- # Set up the config object:
24
- config = Shimmer::Config.new
25
-
26
- # Set some values:
27
- config.somevalue = "Wow"
28
- config.othervalue = ['This', 'is', 'great!']
29
-
30
- # Get some values:
31
- puts config.somevalue # > "Wow"
32
-
33
- # Use namespaces to define very specific values:
34
- config.several.levels.deep.stringvalue = "Your string here"
35
- puts config.several.levels.deep.stringvalue # > "Your string here"
36
-
37
- # Check whether a value exists:
38
- puts config.foo.nil?
39
-
40
- # Set stuff in a namespace using a block:
41
- config.really.deep.namespace do |c|
42
- c.value1 = 1
43
- c.value2 = 2
44
- end
45
-
46
- # Persist values across sessions using localStorage:
47
- config.persist(:cease_and_persist)
48
- config.cease_and_persist = "abc123"
49
-
50
- config2 = Shimmer::Config.new # this loads up a brand new object
51
- config2.persist(:cease_and_persist)
52
-
53
- puts config2.cease_and_persist # > "abc123" Aha! it works!
54
-
55
- # An easier way to persist values by setting initial defaults
56
- # and not overwriting values that get set differently later:
57
- config.persist_defaults do |c|
58
- c.somevalue = "abc"
59
- c.othervalue = 123
60
- end
61
-
62
- # ...user triggers some action...
63
- config.somevalue = "xyz"
64
-
65
- # ...days later on a subsquent browser session...
66
- puts config.somevalue # > "xyz" not "abc" - Yay!
23
+ ```ruby
24
+ # Set up the config object:
25
+ config = Shimmer::Config.new
26
+
27
+ # Set some values:
28
+ config.somevalue = "Wow"
29
+ config.othervalue = ['This', 'is', 'great!']
30
+
31
+ # Get some values:
32
+ puts config.somevalue # > "Wow"
33
+
34
+ # Use namespaces to define very specific values:
35
+ config.several.levels.deep.stringvalue = "Your string here"
36
+ puts config.several.levels.deep.stringvalue # > "Your string here"
37
+
38
+ # Check whether a value exists:
39
+ puts config.foo.nil?
40
+
41
+ # Set stuff in a namespace using a block:
42
+ config.really.deep.namespace do |c|
43
+ c.value1 = 1
44
+ c.value2 = 2
45
+ end
46
+ ```
47
+
48
+ ### Persist values across sessions using the browser's localStorage
49
+
50
+ Normally when you set and retrieve values in a config object, those values are only stored in-memory, which means when you reload the browser the values are no longer available.
51
+
52
+ Shimmer provides a `persist` method that allows you to specify that a value key should be stored in localStorage so that it will be automatically available in a later browser session (or even in the same session if you have a different config instance.
53
+
54
+ ```ruby
55
+ # Persist values across sessions using localStorage:
56
+ config.persist(:cease_and_persist)
57
+ config.cease_and_persist = "abc123"
58
+
59
+ config2 = Shimmer::Config.new # this loads up a brand new object
60
+ config2.persist(:cease_and_persist)
61
+
62
+ puts config2.cease_and_persist # > "abc123" Aha! it works!
63
+ ```
64
+
65
+ If you want to make sure you don't overwrite previous persisted values by setting default values, there is a `persist_defaults` method available. It creates a special block context where you can set numerous values, and those values will _only_ be set if the values aren't already saved in localStorage. Example:
66
+
67
+ ```ruby
68
+ # An easier way to persist values by setting initial defaults
69
+ # and not overwriting values that get set differently later:
70
+ config.persist_defaults do |c|
71
+ c.somevalue = "abc"
72
+ c.othervalue = 123
73
+ end
74
+
75
+ # ...user triggers some action...
76
+ config.somevalue = "xyz"
77
+
78
+ # ...days later on a subsquent browser session...
79
+ puts config.somevalue # > "xyz" not "abc" - Yay!
80
+ ```
81
+
82
+ ### Use Observers to execute code when config values change
83
+
84
+ Shimmer lets you attach an observer (essentially an event handler) to a config object key. The observer will be notified when the value for that key changes, and will receive both the old and the new values as method arguments. Example:
85
+
86
+ ```ruby
87
+ config = Shimmer::Config.new
88
+
89
+ oldval = nil
90
+ newval = nil
91
+
92
+ config.watch do
93
+ on :somevalue do |new, old|
94
+ oldval = old
95
+ newval = new
96
+ end
97
+ end
98
+
99
+ config.somevalue = "Totally cool"
100
+
101
+ puts newval # > "Totally cool"
102
+
103
+ config.somevalue = "Another cool thing"
104
+
105
+ puts newval # > "Another cool thing"
106
+ puts oldval # > "Totally cool"
107
+ ```
67
108
 
68
- For more examples, look at the `config_spec.rb` and `storage_spec.rb` files in the `spec` folder.
109
+ For more examples, look at the `*_spec.rb` files in the `spec` folder.
69
110
 
70
111
  ## Contributing
71
112
 
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Shimmer
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2"
4
4
  end
5
5
  end
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "opal-shimmer"
8
8
  spec.version = Opal::Shimmer::VERSION
9
9
  spec.authors = ["Jared White"]
10
- spec.email = ["jared@ealchemylabs.com"]
10
+ spec.email = ["jared@jaredwhite.com"]
11
11
  spec.description = %q{An application state and configuration management library built with Opal}
12
12
  spec.summary = spec.description
13
13
  spec.homepage = "https://github.com/jaredcwhite/opal-shimmer"
@@ -1,4 +1,5 @@
1
1
  require 'set'
2
2
  require 'json'
3
3
  require 'shimmer/storage'
4
- require 'shimmer/config'
4
+ require 'shimmer/config'
5
+ require 'shimmer/observer'
@@ -9,6 +9,7 @@ module Shimmer
9
9
  @store = {}
10
10
  @persisted_storage = Shimmer::Storage.new(self)
11
11
  @in_persisting_block = false
12
+ @observer = Shimmer::Observer.new(self)
12
13
  end
13
14
 
14
15
  def parent_level
@@ -23,19 +24,28 @@ module Shimmer
23
24
 
24
25
  if method_name[-1] == "="
25
26
  save_key = method_name[0..-2]
27
+
26
28
  if @in_persisting_block
27
29
  unless @persisted_storage.should_include?(save_key)
28
30
  @persisted_storage.should_include(save_key)
29
31
  end
30
32
  unless @persisted_storage.include?(save_key)
31
33
  @persisted_storage.save_value(save_key, args[0])
34
+ @observer.call_watcher(save_key, nil, args[0])
35
+ else
36
+ @observer.call_watcher(save_key, nil, @persisted_storage.load_value(save_key))
32
37
  end
33
38
  elsif !@in_persisting_block and @persisted_storage.should_include?(save_key)
39
+ old_value = @persisted_storage.load_value(save_key)
34
40
  @store[save_key] = args[0]
35
41
  @persisted_storage.save_value(save_key, args[0])
42
+ @observer.call_watcher(save_key, old_value, @store[save_key])
36
43
  else
44
+ old_value = @store[save_key]
37
45
  @store[save_key] = args[0]
46
+ @observer.call_watcher(save_key, old_value, @store[save_key])
38
47
  end
48
+
39
49
  else
40
50
  if include?(method_name)
41
51
  yield @store[method_name] if block
@@ -122,6 +132,15 @@ module Shimmer
122
132
  def to_h
123
133
  @store
124
134
  end
135
+
136
+
137
+ ### Observer setup
138
+ def watch(&block)
139
+ watchdsl = @observer.dsl
140
+ if block_given?
141
+ watchdsl.instance_eval(&block)
142
+ end
143
+ end
125
144
  end
126
145
 
127
146
  end
@@ -0,0 +1,36 @@
1
+ module Shimmer
2
+ class Observer
3
+ def initialize(config_object)
4
+ @config_object = config_object
5
+ @handlers = {}
6
+ @dsl = DSL.new(self)
7
+ end
8
+
9
+ def add_watcher(key, block)
10
+ @handlers[key] = block
11
+ end
12
+
13
+ def call_watcher(key, old, new)
14
+ if @handlers[key]
15
+ @handlers[key].call(new, old, @config_object)
16
+ end
17
+ end
18
+
19
+ def dsl
20
+ @dsl
21
+ end
22
+
23
+ class DSL
24
+ def initialize(observer)
25
+ @observer = observer
26
+ end
27
+ def on(key, passed_method=nil, &block)
28
+ if passed_method
29
+ @observer.add_watcher(key, passed_method)
30
+ else
31
+ @observer.add_watcher(key, block)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ class CallbackTest
4
+ attr_accessor :oldval, :newval
5
+ def initialize
6
+ self.oldval = "foo"
7
+ self.newval = "bar"
8
+ end
9
+ def check_values(new, old, value_config)
10
+ self.oldval = old
11
+ self.newval = new
12
+ end
13
+ end
14
+
15
+ describe "Shimmer::Observer" do
16
+ let(:config) { config = Shimmer::Config.new }
17
+
18
+ it "can observe stuff" do
19
+ oldval = "foo"
20
+ newval = "bar"
21
+
22
+ config.watch do
23
+ on :somevalue do |new, old|
24
+ oldval = old
25
+ newval = new
26
+ end
27
+ end
28
+
29
+ config.somevalue = "Totally cool"
30
+
31
+ expect(oldval).to eq(nil)
32
+ expect(newval).to eq("Totally cool")
33
+ end
34
+ it "can continually observe stuff and access other config values" do
35
+ oldval = "foo"
36
+ newval = "bar"
37
+
38
+ config.watch do
39
+ on :somevalue do |new, old, value_config|
40
+ oldval = "#{value_config.anothervalue} #{old}"
41
+ newval = "#{new} #{value_config.anothervalue}"
42
+ end
43
+ end
44
+
45
+ config.anothervalue = 10
46
+ config.somevalue = "Totally cool"
47
+ config.somevalue = 543
48
+
49
+ expect(oldval).to eq("10 Totally cool")
50
+ expect(newval).to eq("543 10")
51
+
52
+ end
53
+ it "can call a method of an object as the observer handler" do
54
+ callback_test = CallbackTest.new
55
+
56
+ config.callback_value = "Old stuff"
57
+
58
+ config.watch do
59
+ on :callback_value, callback_test.method(:check_values)
60
+ end
61
+
62
+ config.callback_value = "Totally awesome"
63
+
64
+ expect(callback_test.oldval).to eq("Old stuff")
65
+ expect(callback_test.newval).to eq("Totally awesome")
66
+ end
67
+ it "works with persisted items as well" do
68
+ newval = "foo"
69
+ oldval = "bar"
70
+ newsomeval = "foo"
71
+ oldsomeval = "bar"
72
+
73
+ config.watch do
74
+ on :somevalue do |new, old|
75
+ newsomeval = new
76
+ oldsomeval = old
77
+ end
78
+ on :othervalue do |new, old|
79
+ newval = new
80
+ oldval = old
81
+ end
82
+ end
83
+
84
+ `window.localStorage.removeItem('config.somevalue')`
85
+ `window.localStorage.removeItem('config.othervalue')`
86
+
87
+ `window.localStorage['config.othervalue'] = 321`
88
+
89
+ config.persist_defaults do |c|
90
+ c.somevalue = "abc"
91
+ c.othervalue = 123
92
+ end
93
+
94
+ expect(oldsomeval).to eq(nil)
95
+ expect(newsomeval).to eq("abc")
96
+
97
+ expect(oldval).to eq(nil)
98
+ expect(newval).to eq(321)
99
+
100
+ config.othervalue = 456
101
+ config.somevalue = "def"
102
+
103
+ expect(oldsomeval).to eq("abc")
104
+ expect(newsomeval).to eq("def")
105
+
106
+ expect(oldval).to eq(321)
107
+ expect(newval).to eq(456)
108
+ end
109
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-shimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-10 00:00:00.000000000 Z
11
+ date: 2015-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
@@ -69,7 +69,7 @@ dependencies:
69
69
  description: An application state and configuration management library built with
70
70
  Opal
71
71
  email:
72
- - jared@ealchemylabs.com
72
+ - jared@jaredwhite.com
73
73
  executables: []
74
74
  extensions: []
75
75
  extra_rdoc_files: []
@@ -87,8 +87,10 @@ files:
87
87
  - opal-shimmer.gemspec
88
88
  - opal/shimmer.rb
89
89
  - opal/shimmer/config.rb
90
+ - opal/shimmer/observer.rb
90
91
  - opal/shimmer/storage.rb
91
92
  - spec/config_spec.rb
93
+ - spec/observer_spec.rb
92
94
  - spec/spec_helper.rb
93
95
  - spec/storage_spec.rb
94
96
  homepage: https://github.com/jaredcwhite/opal-shimmer
@@ -117,5 +119,6 @@ specification_version: 4
117
119
  summary: An application state and configuration management library built with Opal
118
120
  test_files:
119
121
  - spec/config_spec.rb
122
+ - spec/observer_spec.rb
120
123
  - spec/spec_helper.rb
121
124
  - spec/storage_spec.rb