opal-shimmer 0.1.2 → 0.2

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