slender_data 0.1.0
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/slender_data/ajax_loader.coffee +76 -0
- data/app/assets/javascripts/slender_data/cache.coffee +63 -0
- data/app/assets/javascripts/slender_data/indexed_cache.coffee +32 -0
- data/app/assets/javascripts/slender_data/persistence_manager.coffee +239 -0
- data/app/assets/javascripts/slender_data/tools.coffee +31 -0
- data/app/assets/javascripts/slender_data.js +8 -0
- data/lib/slender_data/engine.rb +5 -0
- data/lib/slender_data/version.rb +3 -0
- data/lib/slender_data.rb +4 -0
- data/lib/tasks/slender_data_tasks.rake +4 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1deea5d8aa969cdc2e213cb39e50b526a00615c0
|
4
|
+
data.tar.gz: 5b89a6bd314958eef91ddf872db9d10763f609d9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b3df0aa35a568a60aa088320e254183d632357f5ecee53b0f47a2ba900113a3fb546e6220f3b50890388f8e67e87c71c5e71db3a2f55563dd3c1c7e4ab14ccf1
|
7
|
+
data.tar.gz: 916850fc041b71ae70fc6c9d97308a7713f78d4ac41f6d4a7ac324f120db9f604f5c5fe6bb20f1c25da2b023822759b42bb745eacd6e5f4e2f665608324fe38c
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'SlenderData'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
Bundler::GemHelper.install_tasks
|
22
|
+
|
23
|
+
task :default => 'app:konacha:run'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#= require slender_data/cache
|
2
|
+
|
3
|
+
# A generic ajax loader for parallel GET requests.
|
4
|
+
# Prevents duplicate requests, caches the responses
|
5
|
+
# to answer subsequent requests immediately
|
6
|
+
# without additional server requests.
|
7
|
+
#
|
8
|
+
# Warning: Caches the responses, so once a request is cached,
|
9
|
+
# any new content on the same URL will not be visible!
|
10
|
+
class slender_data.AjaxLoader
|
11
|
+
|
12
|
+
constructor: (params = {}) ->
|
13
|
+
|
14
|
+
# Caches the callbacks.
|
15
|
+
@cb_cache = new slender_data.Cache()
|
16
|
+
|
17
|
+
# Whether to perform caching of data.
|
18
|
+
# Default: no.
|
19
|
+
@caching = !!params.caching
|
20
|
+
|
21
|
+
# Caches the data loaded.
|
22
|
+
@data_cache = new slender_data.Cache()
|
23
|
+
|
24
|
+
# The number of currently running loading operations.
|
25
|
+
@loader_count = 0
|
26
|
+
|
27
|
+
|
28
|
+
# The different events that this class can fire.
|
29
|
+
@events =
|
30
|
+
AJAX_LOADING: 'AJAX_LOADING'
|
31
|
+
AJAX_LOADED: 'AJAX_LOADED'
|
32
|
+
|
33
|
+
|
34
|
+
# Loads the data from the given URL asynchronously.
|
35
|
+
get: (url, callback) ->
|
36
|
+
|
37
|
+
# Return immediately if we have cached data.
|
38
|
+
if @caching
|
39
|
+
cached_data = @data_cache.get url
|
40
|
+
return callback(cached_data) if cached_data?
|
41
|
+
|
42
|
+
# Here, we have no cached data. Check
|
43
|
+
|
44
|
+
# If a GET call to this URL is already in progress -->
|
45
|
+
# add the given callback to the list of waiting callbacks.
|
46
|
+
request_in_progress = @cb_cache.get url
|
47
|
+
return request_in_progress.push(callback) if request_in_progress?
|
48
|
+
|
49
|
+
# Here, no request is currently in progress --> start a new one.
|
50
|
+
|
51
|
+
# Add callback to callback list.
|
52
|
+
@cb_cache.add url, [callback]
|
53
|
+
|
54
|
+
# Fire 'loading' event if this is the start of a loading operation.
|
55
|
+
@loader_count++
|
56
|
+
if @loader_count == 1
|
57
|
+
$('body').trigger slender_data.AjaxLoader.events.AJAX_LOADING
|
58
|
+
|
59
|
+
# Perform the request.
|
60
|
+
jQuery.get url, (data) =>
|
61
|
+
|
62
|
+
# Add result to cache.
|
63
|
+
if @caching
|
64
|
+
@data_cache.add url, data
|
65
|
+
|
66
|
+
# Call callbacks.
|
67
|
+
cb(data) for cb in @cb_cache.get url
|
68
|
+
|
69
|
+
# Remove request from callback list.
|
70
|
+
@cb_cache.remove url
|
71
|
+
|
72
|
+
# Fire 'loaded' event.
|
73
|
+
@loader_count--
|
74
|
+
if @loader_count == 0
|
75
|
+
$('body').trigger slender_data.AjaxLoader.events.AJAX_LOADED
|
76
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# A generic cache.
|
2
|
+
# Stores key-value pairs.
|
3
|
+
class slender_data.Cache
|
4
|
+
|
5
|
+
constructor: ->
|
6
|
+
|
7
|
+
# Container for the cached objects.
|
8
|
+
@cache = {}
|
9
|
+
|
10
|
+
|
11
|
+
# Adds the given entry to the cache.
|
12
|
+
# Overwrites existing entries.
|
13
|
+
add: (key, value) ->
|
14
|
+
@cache[key] = value
|
15
|
+
|
16
|
+
|
17
|
+
# Returns the entry with the given key from the cache, or NULL if no entry exists.
|
18
|
+
get: (key) ->
|
19
|
+
@cache[key]
|
20
|
+
|
21
|
+
|
22
|
+
# Looks up several entries at once.
|
23
|
+
# Returns a hash of found entries, and a list of missing entries.
|
24
|
+
get_many: (keys) ->
|
25
|
+
result = { found: {}, missing: [] }
|
26
|
+
for key in keys
|
27
|
+
do (key) =>
|
28
|
+
value = @cache[key]
|
29
|
+
if value
|
30
|
+
result.found[key] = value
|
31
|
+
else
|
32
|
+
result.missing.push key
|
33
|
+
result
|
34
|
+
getMany: Cache::get_many
|
35
|
+
|
36
|
+
|
37
|
+
# Returns the number of cached objects.
|
38
|
+
length: () ->
|
39
|
+
slender_data.object_length @cache
|
40
|
+
|
41
|
+
|
42
|
+
# Removes the entry with the given key.
|
43
|
+
remove: (key) =>
|
44
|
+
delete @cache[key]
|
45
|
+
|
46
|
+
|
47
|
+
# Removes all entries with the given keys.
|
48
|
+
remove_many: (keys) ->
|
49
|
+
@remove(key) for key in keys
|
50
|
+
|
51
|
+
|
52
|
+
# Replaces the cache with the given data.
|
53
|
+
# When 'key' is given, treats 'data' as an array of objects, and indexes each element by the given key.
|
54
|
+
# When 'key' is not given, treats 'data' as an already indexed hash object.
|
55
|
+
replace_all: (data, key) ->
|
56
|
+
if key
|
57
|
+
# Key given --> index the data array.
|
58
|
+
@add(entry[key], entry) for entry in data
|
59
|
+
else
|
60
|
+
# Key not given --> use data as the new cache.
|
61
|
+
@cache = data
|
62
|
+
replaceAll: Cache::replace_all
|
63
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#= require slender_data/cache
|
2
|
+
|
3
|
+
# Provides fast and convenient retrieval of hash objects
|
4
|
+
# by indexing them on a given key column.
|
5
|
+
class slender_data.IndexedCache
|
6
|
+
|
7
|
+
constructor: (@key = 'id') ->
|
8
|
+
@cache = new slender_data.Cache
|
9
|
+
|
10
|
+
|
11
|
+
add: (entry) ->
|
12
|
+
@cache.add entry[@key], entry
|
13
|
+
|
14
|
+
|
15
|
+
add_all: (entries) ->
|
16
|
+
@add(entry) for entry in entries
|
17
|
+
|
18
|
+
|
19
|
+
remove: (entry_id) ->
|
20
|
+
@cache.remove entry_id
|
21
|
+
|
22
|
+
|
23
|
+
remove_many: (entry_ids) ->
|
24
|
+
@cache.remove_many entry_ids
|
25
|
+
|
26
|
+
|
27
|
+
get: (key) ->
|
28
|
+
@cache.get key
|
29
|
+
|
30
|
+
|
31
|
+
length: => @cache.length()
|
32
|
+
|
@@ -0,0 +1,239 @@
|
|
1
|
+
#= require slender_data/ajax_loader
|
2
|
+
#= require slender_data/indexed_cache
|
3
|
+
#= require slender_data/tools
|
4
|
+
|
5
|
+
# Provides persistence services for data models.
|
6
|
+
#
|
7
|
+
# This class operates against a standard RESTful data API, whole path is given in params.url.
|
8
|
+
# In addition to the standard RESTful routes, the data API is expected to support these methods for performance reasons:
|
9
|
+
# * DELETE /entries: Delete a whole batch of entries at once. The ids of the entries to delete are given as a JSON hash in the body of the request.
|
10
|
+
# *
|
11
|
+
class slender_data.PersistenceManager
|
12
|
+
|
13
|
+
constructor: (params) ->
|
14
|
+
|
15
|
+
# Copy of the data as it is on the server.
|
16
|
+
@server_data = new slender_data.IndexedCache
|
17
|
+
|
18
|
+
# Copy of the data as it is on the client.
|
19
|
+
@client_data = new slender_data.IndexedCache
|
20
|
+
|
21
|
+
# The base url on the server. Expected to be a fully RESTful API.
|
22
|
+
@base_url = params.url
|
23
|
+
|
24
|
+
# Name of the 'id' column for models.
|
25
|
+
@key = params.key or 'id'
|
26
|
+
|
27
|
+
# Name of the model class (e.g. "user").
|
28
|
+
@model_name = params.model_name
|
29
|
+
|
30
|
+
# For handling parallel requests to the server.
|
31
|
+
@loader = new slender_data.AjaxLoader { cache: no }
|
32
|
+
|
33
|
+
|
34
|
+
# Adds the given data objects to the server cache.
|
35
|
+
add_all: (data) ->
|
36
|
+
@server_data.add_all data
|
37
|
+
|
38
|
+
|
39
|
+
# Returns an array containing only the changed objects.
|
40
|
+
# Each object contains only the changed columns + key column.
|
41
|
+
changed_objects_columns: (objects) ->
|
42
|
+
slender_data.tap [], (result) =>
|
43
|
+
for object in objects
|
44
|
+
diff = slender_data.object_diff @server_data.get(object[@key]), object
|
45
|
+
continue if slender_data.object_length(diff) == 0
|
46
|
+
diff[@key] = object[@key]
|
47
|
+
result.push(diff)
|
48
|
+
|
49
|
+
|
50
|
+
# Returns the URL to access the collection of objects.
|
51
|
+
collection_url: ->
|
52
|
+
"#{@base_url}.json"
|
53
|
+
|
54
|
+
|
55
|
+
# Creates the given object on the server.
|
56
|
+
create: (obj, success_callback, error_callback) ->
|
57
|
+
data = {}
|
58
|
+
data[@model_name] = obj
|
59
|
+
|
60
|
+
jQuery.ajax
|
61
|
+
url: @collection_url()
|
62
|
+
type: 'POST'
|
63
|
+
data: data
|
64
|
+
success: (server_response) =>
|
65
|
+
server_obj = server_response[@model_name]
|
66
|
+
@server_data.add server_obj
|
67
|
+
success_callback server_obj
|
68
|
+
error: (xhr) =>
|
69
|
+
error_callback(xhr.responseText) if error_callback
|
70
|
+
|
71
|
+
|
72
|
+
# Deletes the given object from the server.
|
73
|
+
delete: (obj, success_callback, error_callback) ->
|
74
|
+
@client_data.remove obj
|
75
|
+
@server_data.remove obj
|
76
|
+
jQuery.ajax
|
77
|
+
url: @entry_url(obj)
|
78
|
+
type: 'DELETE'
|
79
|
+
success: ->
|
80
|
+
success_callback() if success_callback?
|
81
|
+
error: (xhr) ->
|
82
|
+
error_callback(xhr.responseText) if error_callback
|
83
|
+
|
84
|
+
|
85
|
+
# Deletes the given objects from the server.
|
86
|
+
delete_many: (object_ids, success_callback, error_callback) ->
|
87
|
+
@client_data.remove_many object_ids
|
88
|
+
@server_data.remove_many object_ids
|
89
|
+
jQuery.ajax
|
90
|
+
url: @base_url
|
91
|
+
type: 'DELETE'
|
92
|
+
data: {ids: object_ids}
|
93
|
+
success: ->
|
94
|
+
success_callback() if success_callback?
|
95
|
+
error: (xhr) ->
|
96
|
+
error_callback(xhr.responseText) if error_callback
|
97
|
+
|
98
|
+
|
99
|
+
# Returns the url to access a single entry.
|
100
|
+
entry_url: (entry) ->
|
101
|
+
"#{@base_url}/#{entry[@key]}.json"
|
102
|
+
|
103
|
+
|
104
|
+
# Returns the url to access the collection of entries.
|
105
|
+
entries_url: ->
|
106
|
+
"#{@base_url}.json"
|
107
|
+
|
108
|
+
|
109
|
+
# Returns the cached data object, or undefined.
|
110
|
+
get_cached: (key) ->
|
111
|
+
|
112
|
+
# Try to use client_data cache.
|
113
|
+
client_obj = @client_data.get key
|
114
|
+
return client_obj if client_obj
|
115
|
+
|
116
|
+
# No data in client cache --> try to use server cache.
|
117
|
+
server_obj = @server_data.get key
|
118
|
+
if server_obj
|
119
|
+
client_obj = slender_data.clone_hash server_obj
|
120
|
+
@client_data.add client_obj
|
121
|
+
return client_obj
|
122
|
+
|
123
|
+
# Object not found in client or server cache.
|
124
|
+
return undefined
|
125
|
+
|
126
|
+
|
127
|
+
# Returns the entry with the given key.
|
128
|
+
load: (key, success_callback) ->
|
129
|
+
|
130
|
+
# Try to load from cache.
|
131
|
+
return success_callback(entry) if entry = @get_cached key
|
132
|
+
|
133
|
+
# No data on client at all --> load data from server.
|
134
|
+
@loader.get "#{@base_url}/#{key}", (server_entry) =>
|
135
|
+
@server_data.add server_entry
|
136
|
+
client_entry = slender_data.clone_hash server_entry
|
137
|
+
@client_data.add client_entry
|
138
|
+
success_callback client_entry
|
139
|
+
|
140
|
+
|
141
|
+
# Loads all objects from the server.
|
142
|
+
# Provides the given params as parameters to the GET request.
|
143
|
+
load_all: (params, success_callback, error_callback) ->
|
144
|
+
jQuery.ajax
|
145
|
+
url: @collection_url()
|
146
|
+
cache: no
|
147
|
+
data: params
|
148
|
+
success: (data) =>
|
149
|
+
@server_data.add_all data
|
150
|
+
success_callback() if success_callback
|
151
|
+
error: (xhr) ->
|
152
|
+
error_callback(xhr.responseText) if error_callback
|
153
|
+
|
154
|
+
|
155
|
+
# Loads all entries with the given ids.
|
156
|
+
load_many: (ids, success_callback) ->
|
157
|
+
missing_ids = []
|
158
|
+
entries = []
|
159
|
+
$.each ids, (pos, id) =>
|
160
|
+
entry = @get_cached id
|
161
|
+
if entry
|
162
|
+
entries.push entry
|
163
|
+
else
|
164
|
+
missing_ids.push id
|
165
|
+
|
166
|
+
if missing_ids.length == 0
|
167
|
+
return success_callback(entries)
|
168
|
+
|
169
|
+
alert "uncached entries found: #{missing_ids}"
|
170
|
+
|
171
|
+
|
172
|
+
# Saves the given object.
|
173
|
+
# Does the right thing (create or update) dependent on
|
174
|
+
# whether the object already has a key parameter.
|
175
|
+
save: (obj, success_callback, error_callback) ->
|
176
|
+
if obj[@key]?
|
177
|
+
@update obj, success_callback, error_callback
|
178
|
+
else
|
179
|
+
@create obj, success_callback, error_callback
|
180
|
+
|
181
|
+
|
182
|
+
# Updates the given object.
|
183
|
+
#
|
184
|
+
# The given object must exist on the server already,
|
185
|
+
# and have a proper value in the key attribute.
|
186
|
+
update: (obj, success_callback, error_callback) ->
|
187
|
+
|
188
|
+
# Handle updating several objects.
|
189
|
+
return @update_many(obj, success_callback, error_callback) if $.type(obj) == 'array'
|
190
|
+
|
191
|
+
# Create a new hash, containing only the changed attributes between obj and it's replica in @server_data.
|
192
|
+
diff_obj = slender_data.object_diff @server_data.get(obj[@key]), obj
|
193
|
+
if slender_data.object_length(diff_obj) == 0
|
194
|
+
success_callback obj if success_callback
|
195
|
+
return
|
196
|
+
|
197
|
+
# Send to server
|
198
|
+
data = {}
|
199
|
+
data[@model_name] = diff_obj
|
200
|
+
jQuery.ajax
|
201
|
+
url: @entry_url(obj)
|
202
|
+
type: 'PUT'
|
203
|
+
data: data
|
204
|
+
success: (server_response) =>
|
205
|
+
server_obj = server_response[@model_name]
|
206
|
+
@server_data.add server_obj
|
207
|
+
client_obj = slender_data.clone_hash server_obj
|
208
|
+
@client_data.add client_obj
|
209
|
+
success_callback client_obj if success_callback
|
210
|
+
error: (xhr) ->
|
211
|
+
error_callback(xhr.responseText) if error_callback
|
212
|
+
|
213
|
+
|
214
|
+
# Bulk-updates the given objects.
|
215
|
+
# All the existing objects must exist on the server already,
|
216
|
+
# and have a value in the key attribute.
|
217
|
+
update_many: (objects, success_callback, error_callback) ->
|
218
|
+
|
219
|
+
# Find all objects that have been changed on the client.
|
220
|
+
diff_objects = @changed_objects_columns objects
|
221
|
+
|
222
|
+
# Send to server
|
223
|
+
data = {}
|
224
|
+
data["#{@model_name}s"] = diff_objects
|
225
|
+
jQuery.ajax
|
226
|
+
url: @entries_url()
|
227
|
+
type: 'PUT'
|
228
|
+
data: data
|
229
|
+
success: (server_response) =>
|
230
|
+
server_objects = server_response["#{@model_name}s"]
|
231
|
+
client_objects = (for server_object in server_objects
|
232
|
+
@server_data.add server_object
|
233
|
+
client_object = slender_data.clone_hash server_object
|
234
|
+
@client_data.add client_object
|
235
|
+
client_object)
|
236
|
+
success_callback(client_objects) if success_callback
|
237
|
+
error: (xhr) ->
|
238
|
+
error_callback(xhr.responseText) if error_callback
|
239
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Returns a replica of the given hash.
|
2
|
+
# Don't use this method for real objects with superclasses, prototypes, and stuff.
|
3
|
+
slender_data.clone_hash = (obj) ->
|
4
|
+
result = {}
|
5
|
+
result[key] = value for own key, value of obj
|
6
|
+
result
|
7
|
+
|
8
|
+
|
9
|
+
# Returns an object that contains only the attributes
|
10
|
+
# that are different between obj_1 and obj_2.
|
11
|
+
# Only looks for changed attributes, not missing attributes.
|
12
|
+
slender_data.object_diff = (obj_1, obj_2) ->
|
13
|
+
result = {}
|
14
|
+
for own key, value_2 of obj_2
|
15
|
+
do (key, value_2) ->
|
16
|
+
value_1 = obj_1[key]
|
17
|
+
result[key] = value_2 if value_1 != value_2
|
18
|
+
result
|
19
|
+
|
20
|
+
|
21
|
+
# Returns the number of attributes of the given object.
|
22
|
+
# NOTE(KG): This doesn't work in IE8.
|
23
|
+
slender_data.object_length = (obj) ->
|
24
|
+
Object.keys(obj).length
|
25
|
+
|
26
|
+
|
27
|
+
# Allows to populate the given object through a callback.
|
28
|
+
slender_data.tap = (obj, callback) ->
|
29
|
+
callback obj
|
30
|
+
obj
|
31
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
//= require_self
|
2
|
+
//= require ./slender_data/tools
|
3
|
+
//= require ./slender_data/cache
|
4
|
+
//= require ./slender_data/indexed_cache
|
5
|
+
//= require ./slender_data/ajax_loader
|
6
|
+
//= require ./slender_data/persistence_manager
|
7
|
+
|
8
|
+
window.slender_data = window.slender_data || {}
|
data/lib/slender_data.rb
ADDED
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slender_data
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Goslar
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: coffee-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard-livereload
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: selenium-webdriver
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: uglifier
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Provides simple and extensible data management services to JavaScript
|
112
|
+
applications.
|
113
|
+
email:
|
114
|
+
- kevin.goslar@gmail.com
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- app/assets/javascripts/slender_data/ajax_loader.coffee
|
120
|
+
- app/assets/javascripts/slender_data/cache.coffee
|
121
|
+
- app/assets/javascripts/slender_data/indexed_cache.coffee
|
122
|
+
- app/assets/javascripts/slender_data/persistence_manager.coffee
|
123
|
+
- app/assets/javascripts/slender_data/tools.coffee
|
124
|
+
- app/assets/javascripts/slender_data.js
|
125
|
+
- lib/slender_data/engine.rb
|
126
|
+
- lib/slender_data/version.rb
|
127
|
+
- lib/slender_data.rb
|
128
|
+
- lib/tasks/slender_data_tasks.rake
|
129
|
+
- MIT-LICENSE
|
130
|
+
- Rakefile
|
131
|
+
homepage: http://github.com/kevgo/slender_data
|
132
|
+
licenses: []
|
133
|
+
metadata: {}
|
134
|
+
post_install_message:
|
135
|
+
rdoc_options: []
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 2.0.3
|
151
|
+
signing_key:
|
152
|
+
specification_version: 4
|
153
|
+
summary: A JS micro-framework for lightweight AJAX data management against RESTful
|
154
|
+
APIs.
|
155
|
+
test_files: []
|