slender_data 0.5.0 → 0.6.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.
Files changed (261) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/slender_data.coffee +14 -0
  3. data/app/assets/javascripts/slender_data/brest_loader.coffee +139 -0
  4. data/app/assets/javascripts/slender_data/cache.coffee +9 -24
  5. data/app/assets/javascripts/slender_data/entry_store.coffee +107 -0
  6. data/app/assets/javascripts/slender_data/loading_indicator.coffee +28 -0
  7. data/app/assets/javascripts/slender_data/loading_tracker.coffee +74 -0
  8. data/app/assets/javascripts/slender_data/parameterizable.coffee +50 -0
  9. data/app/assets/javascripts/slender_data/persistence_manager.coffee +114 -233
  10. data/app/assets/javascripts/slender_data/queries/base_query.coffee +32 -0
  11. data/app/assets/javascripts/slender_data/queries/multi_query.coffee +91 -0
  12. data/app/assets/javascripts/slender_data/queries/single_query.coffee +81 -0
  13. data/app/assets/javascripts/slender_data/query_cache.coffee +87 -0
  14. data/lib/slender_data/version.rb +1 -1
  15. data/spec/dummy/Rakefile +6 -0
  16. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  17. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  18. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  19. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  20. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  21. data/spec/dummy/bin/bundle +3 -0
  22. data/spec/dummy/bin/rails +4 -0
  23. data/spec/dummy/bin/rake +4 -0
  24. data/spec/dummy/config.ru +4 -0
  25. data/spec/dummy/config/application.rb +23 -0
  26. data/spec/dummy/config/boot.rb +5 -0
  27. data/spec/dummy/config/database.yml +25 -0
  28. data/spec/dummy/config/environment.rb +5 -0
  29. data/spec/dummy/config/environments/development.rb +31 -0
  30. data/spec/dummy/config/environments/production.rb +80 -0
  31. data/spec/dummy/config/environments/test.rb +36 -0
  32. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  33. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  34. data/spec/dummy/config/initializers/inflections.rb +16 -0
  35. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  36. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  37. data/spec/dummy/config/initializers/session_store.rb +3 -0
  38. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  39. data/spec/dummy/config/locales/en.yml +23 -0
  40. data/spec/dummy/config/routes.rb +4 -0
  41. data/spec/dummy/db/test.sqlite3 +0 -0
  42. data/spec/dummy/lib/tasks/tasks.rake +13 -0
  43. data/spec/dummy/log/development.log +349013 -0
  44. data/spec/dummy/log/test.log +883 -0
  45. data/spec/dummy/public/404.html +58 -0
  46. data/spec/dummy/public/422.html +58 -0
  47. data/spec/dummy/public/500.html +57 -0
  48. data/spec/dummy/public/favicon.ico +0 -0
  49. data/spec/dummy/spec/javascripts/brest_loader_spec.coffee +314 -0
  50. data/spec/dummy/spec/javascripts/cache_spec.coffee +93 -0
  51. data/spec/dummy/spec/javascripts/entry_store_spec.coffee +315 -0
  52. data/spec/dummy/spec/javascripts/jquery.js +6 -0
  53. data/spec/dummy/spec/javascripts/loading_tracker_spec.coffee +95 -0
  54. data/spec/dummy/spec/javascripts/parameterizable_spec.coffee +138 -0
  55. data/spec/dummy/spec/javascripts/persistence_manager_spec.coffee +659 -0
  56. data/spec/dummy/spec/javascripts/queries/base_query_spec.coffee +41 -0
  57. data/spec/dummy/spec/javascripts/queries/multi_query_spec.coffee +143 -0
  58. data/spec/dummy/spec/javascripts/queries/single_query_spec.coffee +112 -0
  59. data/spec/dummy/spec/javascripts/query_cache_spec.coffee +347 -0
  60. data/spec/dummy/spec/javascripts/sinon-chai.js +109 -0
  61. data/spec/dummy/spec/javascripts/sinon.js +4290 -0
  62. data/spec/dummy/spec/javascripts/spec_helper.coffee +23 -0
  63. data/spec/dummy/tmp/cache/assets/development/sprockets/02dabf70b4ae4a034f349ce89b4831d8 +0 -0
  64. data/spec/dummy/tmp/cache/assets/development/sprockets/031a6c2e3a4e952151301446bd3fc16d +0 -0
  65. data/spec/dummy/tmp/cache/assets/development/sprockets/0373c4e5507b3195c4ad15224d991609 +0 -0
  66. data/spec/dummy/tmp/cache/assets/development/sprockets/05175bd457a57c3ad73ab9a2c8696c9b +0 -0
  67. data/spec/dummy/tmp/cache/assets/development/sprockets/086e89c7529d5063e771b41793bfe311 +0 -0
  68. data/spec/dummy/tmp/cache/assets/development/sprockets/08b36042c3a4a79ebd9cee8ee1b88e6a +0 -0
  69. data/spec/dummy/tmp/cache/assets/development/sprockets/10513fd445754b59bd6001ea6ee727d9 +0 -0
  70. data/spec/dummy/tmp/cache/assets/development/sprockets/124f6816f926ae28ad20cc56425f3c91 +0 -0
  71. data/spec/dummy/tmp/cache/assets/development/sprockets/12ce2414098e368903aeb9923e275ef7 +0 -0
  72. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  73. data/spec/dummy/tmp/cache/assets/development/sprockets/14eca89f8dccac139fd132de35d22628 +0 -0
  74. data/spec/dummy/tmp/cache/assets/development/sprockets/16c8b12ef6dcb486a7b771e43bbcc117 +0 -0
  75. data/spec/dummy/tmp/cache/assets/development/sprockets/19cdfaa89f900500a03507b86afe1231 +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/1b3a4d533a743ca2ccfbca0986613995 +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/1ca8c5b832302c6c94692d0875a59605 +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/2e2576241d2a4969c9277fe85851c92b +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/2ec1baba6d6dc634d091b3acf8127cf7 +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/2ff315acad8ceec317fd566d792df64f +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/311f68c1b9e342ebab4c92c8cb2b5e54 +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/324a5040c964d5e8d293564383c49b91 +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/3310b5a70d0b220782ab3e87642834e9 +0 -0
  84. data/spec/dummy/tmp/cache/assets/development/sprockets/33ea745e7aa9669831758b7d36db1cb4 +0 -0
  85. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  86. data/spec/dummy/tmp/cache/assets/development/sprockets/3999afdceee7ca8dcf53757221c62d71 +0 -0
  87. data/spec/dummy/tmp/cache/assets/development/sprockets/3ba03b9f1aab60e78424f36e0e6cce6c +0 -0
  88. data/spec/dummy/tmp/cache/assets/development/sprockets/3e9a6ed890157d94f18b480f0079d8e1 +0 -0
  89. data/spec/dummy/tmp/cache/assets/development/sprockets/3ef50ccfe459d5c89ecc79a448586b49 +0 -0
  90. data/spec/dummy/tmp/cache/assets/development/sprockets/46c298dc2ff12ec748c70c017684fc28 +0 -0
  91. data/spec/dummy/tmp/cache/assets/development/sprockets/476318dd8109fbf173335456cabb4128 +0 -0
  92. data/spec/dummy/tmp/cache/assets/development/sprockets/5602ee157ea76a2f44a43739a83b1a6c +0 -0
  93. data/spec/dummy/tmp/cache/assets/development/sprockets/5b390f4782d6b77f5aec7ec56f3ad934 +0 -0
  94. data/spec/dummy/tmp/cache/assets/development/sprockets/5b5a66f4eefc591d284af6535ae474ea +0 -0
  95. data/spec/dummy/tmp/cache/assets/development/sprockets/5c41eeb2e98dc0833647e8547880435e +0 -0
  96. data/spec/dummy/tmp/cache/assets/development/sprockets/5cd2936d626662390288ab4c07ff3957 +0 -0
  97. data/spec/dummy/tmp/cache/assets/development/sprockets/5fd362891a204d492d9fa57ffee6e114 +0 -0
  98. data/spec/dummy/tmp/cache/assets/development/sprockets/643d60abdbcc813c95214920f12f09c3 +0 -0
  99. data/spec/dummy/tmp/cache/assets/development/sprockets/6591bc7545da5a2f5f7dee20b1f110a5 +0 -0
  100. data/spec/dummy/tmp/cache/assets/development/sprockets/6597f36181468ff92ba4284afe001181 +0 -0
  101. data/spec/dummy/tmp/cache/assets/development/sprockets/69b7946c418b75e7ba78f9fc73d3e9b9 +0 -0
  102. data/spec/dummy/tmp/cache/assets/development/sprockets/6c75b81de9afea82a6cbb56749157e3f +0 -0
  103. data/spec/dummy/tmp/cache/assets/development/sprockets/6e4bc63f9308eb5929a77f7607101af1 +0 -0
  104. data/spec/dummy/tmp/cache/assets/development/sprockets/6ee2243cf1cf415b6267b84dd7b8ba77 +0 -0
  105. data/spec/dummy/tmp/cache/assets/development/sprockets/6f8457b4ba418f572891745381a1e0f5 +0 -0
  106. data/spec/dummy/tmp/cache/assets/development/sprockets/6fd5544e52538b06ac40e5b387b020a5 +0 -0
  107. data/spec/dummy/tmp/cache/assets/development/sprockets/6fed8361766f5ae3cbf781986d6945b2 +0 -0
  108. data/spec/dummy/tmp/cache/assets/development/sprockets/70ffa648dbbe0f2431e7f9307b569354 +0 -0
  109. data/spec/dummy/tmp/cache/assets/development/sprockets/731f0bc492f775825f046d500938fc5a +0 -0
  110. data/spec/dummy/tmp/cache/assets/development/sprockets/76153dd2cc3d0c6e584080efb16e872a +0 -0
  111. data/spec/dummy/tmp/cache/assets/development/sprockets/76cd4393e7976d030f4623b8b6b372a0 +0 -0
  112. data/spec/dummy/tmp/cache/assets/development/sprockets/78d5dac5e2f907dd68813ed23a0fd4ac +0 -0
  113. data/spec/dummy/tmp/cache/assets/development/sprockets/7a400f93bfb71a1a11c59b9804adda6d +0 -0
  114. data/spec/dummy/tmp/cache/assets/development/sprockets/7abf5e8d9666225cb1d7881798dbd87a +0 -0
  115. data/spec/dummy/tmp/cache/assets/development/sprockets/7d6f1f3e48f6cc97a9bb4606f8c5a020 +0 -0
  116. data/spec/dummy/tmp/cache/assets/development/sprockets/814ca144649e7dec9e9158b3ec3460f1 +0 -0
  117. data/spec/dummy/tmp/cache/assets/development/sprockets/83de5b2d2c5d49f7737ae1f0316435ec +0 -0
  118. data/spec/dummy/tmp/cache/assets/development/sprockets/84c67faa73fdd082d4bd7f7712cb0499 +0 -0
  119. data/spec/dummy/tmp/cache/assets/development/sprockets/87a6ddc523ccbf2673750499bede3fc9 +0 -0
  120. data/spec/dummy/tmp/cache/assets/development/sprockets/8a90082fa76a7f37dd92a9b9a9b9f593 +0 -0
  121. data/spec/dummy/tmp/cache/assets/development/sprockets/8c5b622a33c6c034ecb4e78f131c5f73 +0 -0
  122. data/spec/dummy/tmp/cache/assets/development/sprockets/8c9851849e82bb9670e56f046df437f9 +0 -0
  123. data/spec/dummy/tmp/cache/assets/development/sprockets/8fc1455d3af69de5da04bf2a2a3f0b74 +0 -0
  124. data/spec/dummy/tmp/cache/assets/development/sprockets/96af98519e5badf206b77c3ecaf86d20 +0 -0
  125. data/spec/dummy/tmp/cache/assets/development/sprockets/98610661915880264fdb51c8f1a14141 +0 -0
  126. data/spec/dummy/tmp/cache/assets/development/sprockets/9a00753cdfb01f357dc39eeada77d0bc +0 -0
  127. data/spec/dummy/tmp/cache/assets/development/sprockets/9ad3db355e00d28ed3faed6dea5b1bff +0 -0
  128. data/spec/dummy/tmp/cache/assets/development/sprockets/9cbb3109d489692fd270c77ffa9d9559 +0 -0
  129. data/spec/dummy/tmp/cache/assets/development/sprockets/a22afac508f5adc12bf48d2f8333b8f7 +0 -0
  130. data/spec/dummy/tmp/cache/assets/development/sprockets/a49d020ee42c78bf7d22a21e8ee3b80f +0 -0
  131. data/spec/dummy/tmp/cache/assets/development/sprockets/a4f4f6c56c368263c0fbcf3f1542aa73 +0 -0
  132. data/spec/dummy/tmp/cache/assets/development/sprockets/a56b8266298c4171918ee403aa1c9e0f +0 -0
  133. data/spec/dummy/tmp/cache/assets/development/sprockets/a73a44bfca198fdf779532b644ec8af5 +0 -0
  134. data/spec/dummy/tmp/cache/assets/development/sprockets/aa4a22da44bd1b7dbdbb18f983d6c09b +0 -0
  135. data/spec/dummy/tmp/cache/assets/development/sprockets/ab0236bf3eac5cd30348c18efce8246b +0 -0
  136. data/spec/dummy/tmp/cache/assets/development/sprockets/abf215c8dc45135a91f4f993514c653f +0 -0
  137. data/spec/dummy/tmp/cache/assets/development/sprockets/ac1b8c30ad00cc489b7ec78bd6e2fc6c +0 -0
  138. data/spec/dummy/tmp/cache/assets/development/sprockets/ae8bd07980ad64ef8e9ac3fe38413c6d +0 -0
  139. data/spec/dummy/tmp/cache/assets/development/sprockets/b1950420978c68074fc6fd81d4320bc0 +0 -0
  140. data/spec/dummy/tmp/cache/assets/development/sprockets/b2d6aa1cb303474ebf3bfc571904ad23 +0 -0
  141. data/spec/dummy/tmp/cache/assets/development/sprockets/b59a10f85562b39fc7dd651965df9cab +0 -0
  142. data/spec/dummy/tmp/cache/assets/development/sprockets/b8d24bca037cf4b0a9e2979c11c8aea8 +0 -0
  143. data/spec/dummy/tmp/cache/assets/development/sprockets/bc2f15f88df08b4265c83133d6107680 +0 -0
  144. data/spec/dummy/tmp/cache/assets/development/sprockets/bd7ddfa86995ff5d259ea37e4a90c51c +0 -0
  145. data/spec/dummy/tmp/cache/assets/development/sprockets/c0515d57887926d6e28a0f87da31ee8e +0 -0
  146. data/spec/dummy/tmp/cache/assets/development/sprockets/c4820232e07d4e298e834c1011a72faa +0 -0
  147. data/spec/dummy/tmp/cache/assets/development/sprockets/c6babc078901541de3f4cb5cc2703bea +0 -0
  148. data/spec/dummy/tmp/cache/assets/development/sprockets/c9635dd5cbd79bdd9c58a89f6ea01595 +0 -0
  149. data/spec/dummy/tmp/cache/assets/development/sprockets/c9962abce37f5a56d5f05afe1edfe1b8 +0 -0
  150. data/spec/dummy/tmp/cache/assets/development/sprockets/cce1f28f0d1f5c2817e6eaf392bac615 +0 -0
  151. data/spec/dummy/tmp/cache/assets/development/sprockets/d37cae0bfdf135e6e71bcd0572bef329 +0 -0
  152. data/spec/dummy/tmp/cache/assets/development/sprockets/d4956056f6f35287a04295df6e52575d +0 -0
  153. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  154. data/spec/dummy/tmp/cache/assets/development/sprockets/dc54acb6b8cd4b84b13f440d57db37b1 +0 -0
  155. data/spec/dummy/tmp/cache/assets/development/sprockets/dd51c50b2d8231175e8da83e8b057120 +0 -0
  156. data/spec/dummy/tmp/cache/assets/development/sprockets/dec2df59b57b3639f89847e50416c924 +0 -0
  157. data/spec/dummy/tmp/cache/assets/development/sprockets/df45b0abc2c323093874639ceb72c012 +0 -0
  158. data/spec/dummy/tmp/cache/assets/development/sprockets/e0393ec0ca968f0d4182c82802da79d5 +0 -0
  159. data/spec/dummy/tmp/cache/assets/development/sprockets/e43bfee690613c316a59f122315314e5 +0 -0
  160. data/spec/dummy/tmp/cache/assets/development/sprockets/ed1d892145be7053348b0ba28c27b427 +0 -0
  161. data/spec/dummy/tmp/cache/assets/development/sprockets/ef2b922f05692ba49eb1f68801786b8e +0 -0
  162. data/spec/dummy/tmp/cache/assets/development/sprockets/efec5fde178e0875317a0d380222545d +0 -0
  163. data/spec/dummy/tmp/cache/assets/development/sprockets/f01906d52258e56e92a230dc3e55805d +0 -0
  164. data/spec/dummy/tmp/cache/assets/development/sprockets/f1b4ffa23205a95782c5c5050359429f +0 -0
  165. data/spec/dummy/tmp/cache/assets/development/sprockets/f2080a87aa027245a444b1486dce7792 +0 -0
  166. data/spec/dummy/tmp/cache/assets/development/sprockets/f37842723e3572ba18f02519dab4ee77 +0 -0
  167. data/spec/dummy/tmp/cache/assets/development/sprockets/f72501aca20f34d765720253853e6105 +0 -0
  168. data/spec/dummy/tmp/cache/assets/development/sprockets/f74306735334107c5d17684f524b65cf +0 -0
  169. data/spec/dummy/tmp/cache/assets/development/sprockets/f89dc49f90e98b448540556861f0173e +0 -0
  170. data/spec/dummy/tmp/cache/assets/development/sprockets/feadb1611975b23f2647e1ac656ad90b +0 -0
  171. data/spec/dummy/tmp/cache/assets/development/sprockets/ff445b9646db9910af486791b285b112 +0 -0
  172. data/spec/dummy/tmp/cache/assets/development/sprockets/ffa1eaa25729d9d4cd7e2fd666868936 +0 -0
  173. data/spec/dummy/tmp/cache/assets/test/sprockets/02dabf70b4ae4a034f349ce89b4831d8 +0 -0
  174. data/spec/dummy/tmp/cache/assets/test/sprockets/031a6c2e3a4e952151301446bd3fc16d +0 -0
  175. data/spec/dummy/tmp/cache/assets/test/sprockets/0373c4e5507b3195c4ad15224d991609 +0 -0
  176. data/spec/dummy/tmp/cache/assets/test/sprockets/05175bd457a57c3ad73ab9a2c8696c9b +0 -0
  177. data/spec/dummy/tmp/cache/assets/test/sprockets/086e89c7529d5063e771b41793bfe311 +0 -0
  178. data/spec/dummy/tmp/cache/assets/test/sprockets/08b36042c3a4a79ebd9cee8ee1b88e6a +0 -0
  179. data/spec/dummy/tmp/cache/assets/test/sprockets/10513fd445754b59bd6001ea6ee727d9 +0 -0
  180. data/spec/dummy/tmp/cache/assets/test/sprockets/124f6816f926ae28ad20cc56425f3c91 +0 -0
  181. data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  182. data/spec/dummy/tmp/cache/assets/test/sprockets/14eca89f8dccac139fd132de35d22628 +0 -0
  183. data/spec/dummy/tmp/cache/assets/test/sprockets/16c8b12ef6dcb486a7b771e43bbcc117 +0 -0
  184. data/spec/dummy/tmp/cache/assets/test/sprockets/2b22662f42e9f485aafa6a333faaa256 +0 -0
  185. data/spec/dummy/tmp/cache/assets/test/sprockets/2e2576241d2a4969c9277fe85851c92b +0 -0
  186. data/spec/dummy/tmp/cache/assets/test/sprockets/2ec1baba6d6dc634d091b3acf8127cf7 +0 -0
  187. data/spec/dummy/tmp/cache/assets/test/sprockets/2ff315acad8ceec317fd566d792df64f +0 -0
  188. data/spec/dummy/tmp/cache/assets/test/sprockets/311f68c1b9e342ebab4c92c8cb2b5e54 +0 -0
  189. data/spec/dummy/tmp/cache/assets/test/sprockets/324a5040c964d5e8d293564383c49b91 +0 -0
  190. data/spec/dummy/tmp/cache/assets/test/sprockets/3310b5a70d0b220782ab3e87642834e9 +0 -0
  191. data/spec/dummy/tmp/cache/assets/test/sprockets/33ea745e7aa9669831758b7d36db1cb4 +0 -0
  192. data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  193. data/spec/dummy/tmp/cache/assets/test/sprockets/3999afdceee7ca8dcf53757221c62d71 +0 -0
  194. data/spec/dummy/tmp/cache/assets/test/sprockets/3e9a6ed890157d94f18b480f0079d8e1 +0 -0
  195. data/spec/dummy/tmp/cache/assets/test/sprockets/3ef50ccfe459d5c89ecc79a448586b49 +0 -0
  196. data/spec/dummy/tmp/cache/assets/test/sprockets/46c298dc2ff12ec748c70c017684fc28 +0 -0
  197. data/spec/dummy/tmp/cache/assets/test/sprockets/476318dd8109fbf173335456cabb4128 +0 -0
  198. data/spec/dummy/tmp/cache/assets/test/sprockets/5602ee157ea76a2f44a43739a83b1a6c +0 -0
  199. data/spec/dummy/tmp/cache/assets/test/sprockets/5b390f4782d6b77f5aec7ec56f3ad934 +0 -0
  200. data/spec/dummy/tmp/cache/assets/test/sprockets/5b5a66f4eefc591d284af6535ae474ea +0 -0
  201. data/spec/dummy/tmp/cache/assets/test/sprockets/5cd2936d626662390288ab4c07ff3957 +0 -0
  202. data/spec/dummy/tmp/cache/assets/test/sprockets/643d60abdbcc813c95214920f12f09c3 +0 -0
  203. data/spec/dummy/tmp/cache/assets/test/sprockets/6597f36181468ff92ba4284afe001181 +0 -0
  204. data/spec/dummy/tmp/cache/assets/test/sprockets/6c75b81de9afea82a6cbb56749157e3f +0 -0
  205. data/spec/dummy/tmp/cache/assets/test/sprockets/6e4bc63f9308eb5929a77f7607101af1 +0 -0
  206. data/spec/dummy/tmp/cache/assets/test/sprockets/6ee2243cf1cf415b6267b84dd7b8ba77 +0 -0
  207. data/spec/dummy/tmp/cache/assets/test/sprockets/6f8457b4ba418f572891745381a1e0f5 +0 -0
  208. data/spec/dummy/tmp/cache/assets/test/sprockets/6fd5544e52538b06ac40e5b387b020a5 +0 -0
  209. data/spec/dummy/tmp/cache/assets/test/sprockets/6fed8361766f5ae3cbf781986d6945b2 +0 -0
  210. data/spec/dummy/tmp/cache/assets/test/sprockets/70ffa648dbbe0f2431e7f9307b569354 +0 -0
  211. data/spec/dummy/tmp/cache/assets/test/sprockets/76cd4393e7976d030f4623b8b6b372a0 +0 -0
  212. data/spec/dummy/tmp/cache/assets/test/sprockets/7a400f93bfb71a1a11c59b9804adda6d +0 -0
  213. data/spec/dummy/tmp/cache/assets/test/sprockets/7abf5e8d9666225cb1d7881798dbd87a +0 -0
  214. data/spec/dummy/tmp/cache/assets/test/sprockets/7d6f1f3e48f6cc97a9bb4606f8c5a020 +0 -0
  215. data/spec/dummy/tmp/cache/assets/test/sprockets/814ca144649e7dec9e9158b3ec3460f1 +0 -0
  216. data/spec/dummy/tmp/cache/assets/test/sprockets/83de5b2d2c5d49f7737ae1f0316435ec +0 -0
  217. data/spec/dummy/tmp/cache/assets/test/sprockets/873c5252aa4eab7409b712c5e276bad2 +0 -0
  218. data/spec/dummy/tmp/cache/assets/test/sprockets/87a6ddc523ccbf2673750499bede3fc9 +0 -0
  219. data/spec/dummy/tmp/cache/assets/test/sprockets/8a90082fa76a7f37dd92a9b9a9b9f593 +0 -0
  220. data/spec/dummy/tmp/cache/assets/test/sprockets/8c5b622a33c6c034ecb4e78f131c5f73 +0 -0
  221. data/spec/dummy/tmp/cache/assets/test/sprockets/8c9851849e82bb9670e56f046df437f9 +0 -0
  222. data/spec/dummy/tmp/cache/assets/test/sprockets/8fc1455d3af69de5da04bf2a2a3f0b74 +0 -0
  223. data/spec/dummy/tmp/cache/assets/test/sprockets/98610661915880264fdb51c8f1a14141 +0 -0
  224. data/spec/dummy/tmp/cache/assets/test/sprockets/9a00753cdfb01f357dc39eeada77d0bc +0 -0
  225. data/spec/dummy/tmp/cache/assets/test/sprockets/9ad3db355e00d28ed3faed6dea5b1bff +0 -0
  226. data/spec/dummy/tmp/cache/assets/test/sprockets/a22afac508f5adc12bf48d2f8333b8f7 +0 -0
  227. data/spec/dummy/tmp/cache/assets/test/sprockets/a4f4f6c56c368263c0fbcf3f1542aa73 +0 -0
  228. data/spec/dummy/tmp/cache/assets/test/sprockets/a56b8266298c4171918ee403aa1c9e0f +0 -0
  229. data/spec/dummy/tmp/cache/assets/test/sprockets/a73a44bfca198fdf779532b644ec8af5 +0 -0
  230. data/spec/dummy/tmp/cache/assets/test/sprockets/aa4a22da44bd1b7dbdbb18f983d6c09b +0 -0
  231. data/spec/dummy/tmp/cache/assets/test/sprockets/ab0236bf3eac5cd30348c18efce8246b +0 -0
  232. data/spec/dummy/tmp/cache/assets/test/sprockets/ac1b8c30ad00cc489b7ec78bd6e2fc6c +0 -0
  233. data/spec/dummy/tmp/cache/assets/test/sprockets/ae8bd07980ad64ef8e9ac3fe38413c6d +0 -0
  234. data/spec/dummy/tmp/cache/assets/test/sprockets/b1950420978c68074fc6fd81d4320bc0 +0 -0
  235. data/spec/dummy/tmp/cache/assets/test/sprockets/b2d6aa1cb303474ebf3bfc571904ad23 +0 -0
  236. data/spec/dummy/tmp/cache/assets/test/sprockets/b8d24bca037cf4b0a9e2979c11c8aea8 +0 -0
  237. data/spec/dummy/tmp/cache/assets/test/sprockets/bc2f15f88df08b4265c83133d6107680 +0 -0
  238. data/spec/dummy/tmp/cache/assets/test/sprockets/c9962abce37f5a56d5f05afe1edfe1b8 +0 -0
  239. data/spec/dummy/tmp/cache/assets/test/sprockets/cce1f28f0d1f5c2817e6eaf392bac615 +0 -0
  240. data/spec/dummy/tmp/cache/assets/test/sprockets/d37cae0bfdf135e6e71bcd0572bef329 +0 -0
  241. data/spec/dummy/tmp/cache/assets/test/sprockets/d4956056f6f35287a04295df6e52575d +0 -0
  242. data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  243. data/spec/dummy/tmp/cache/assets/test/sprockets/dc54acb6b8cd4b84b13f440d57db37b1 +0 -0
  244. data/spec/dummy/tmp/cache/assets/test/sprockets/dd51c50b2d8231175e8da83e8b057120 +0 -0
  245. data/spec/dummy/tmp/cache/assets/test/sprockets/df13b2e8a88a9dcdc4a830fdd8f8d7b8 +0 -0
  246. data/spec/dummy/tmp/cache/assets/test/sprockets/df45b0abc2c323093874639ceb72c012 +0 -0
  247. data/spec/dummy/tmp/cache/assets/test/sprockets/e0393ec0ca968f0d4182c82802da79d5 +0 -0
  248. data/spec/dummy/tmp/cache/assets/test/sprockets/e43bfee690613c316a59f122315314e5 +0 -0
  249. data/spec/dummy/tmp/cache/assets/test/sprockets/ed1d892145be7053348b0ba28c27b427 +0 -0
  250. data/spec/dummy/tmp/cache/assets/test/sprockets/ef2b922f05692ba49eb1f68801786b8e +0 -0
  251. data/spec/dummy/tmp/cache/assets/test/sprockets/f01906d52258e56e92a230dc3e55805d +0 -0
  252. data/spec/dummy/tmp/cache/assets/test/sprockets/f1b4ffa23205a95782c5c5050359429f +0 -0
  253. data/spec/dummy/tmp/cache/assets/test/sprockets/f2080a87aa027245a444b1486dce7792 +0 -0
  254. data/spec/dummy/tmp/cache/assets/test/sprockets/f37842723e3572ba18f02519dab4ee77 +0 -0
  255. data/spec/dummy/tmp/cache/assets/test/sprockets/f72501aca20f34d765720253853e6105 +0 -0
  256. data/spec/dummy/tmp/cache/assets/test/sprockets/feadb1611975b23f2647e1ac656ad90b +0 -0
  257. data/spec/dummy/tmp/cache/assets/test/sprockets/ff445b9646db9910af486791b285b112 +0 -0
  258. metadata +499 -6
  259. data/app/assets/javascripts/slender_data.js +0 -8
  260. data/app/assets/javascripts/slender_data/ajax_loader.coffee +0 -76
  261. data/app/assets/javascripts/slender_data/indexed_cache.coffee +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee33cc4f9d5919b3ff1047221a190414a19069d2
4
- data.tar.gz: a1a39aea719c62de60004c370a4ba7864cdf7e9f
3
+ metadata.gz: 039f8fdfcd726201c423f28a0f3bb5128d6c82f9
4
+ data.tar.gz: e9ae11877f924d70673ea8d87367cb5230e34143
5
5
  SHA512:
6
- metadata.gz: 540378e81d3795a257a90f8fc22ca6adc6225f6e9cf3daa8613ce818572ccdfa0d7fb38196d0db346dbafadcc1bcb0abd672bfa35afcf3272b0899d53edaf9c4
7
- data.tar.gz: 9a07f6eca0c9672edfdb7a81ce66b22afcc602233ac80c9550e212ff98129578ba2577ddf36a7da51e5052e6922970467f112137398bd011f775f5df2d89786c
6
+ metadata.gz: d737ee000404b4036b927a0d2fd523dcc8367c5052c859650dca758f7e1398043ad5ac87ae819abbc5d10ae8cd3a5effb19e6588a7c2195a37a0c2a63415f203
7
+ data.tar.gz: 70c48cb3d6b8aed81308ad2333f24b2e0744a220b3a705160e080bbfd45cf4ae5688060c2b5df72e99b8b5fb7df1afc7935cdd00cf5c9226477005e8cee72515
@@ -0,0 +1,14 @@
1
+ #= require_self
2
+ #= require ./slender_data/tools
3
+ #= require ./slender_data/persistence_manager
4
+
5
+ window.slender_data or= {}
6
+
7
+
8
+ # Makes sure the given query is an instance of the given query class.
9
+ # If not, creates an instance of the given query class from the given query.
10
+ slender_data.querify = (query, clazz, params) ->
11
+ if query instanceof clazz
12
+ query
13
+ else
14
+ new clazz query, params
@@ -0,0 +1,139 @@
1
+ #= require slender_data/queries/multi_query
2
+ #= require slender_data/queries/single_query
3
+ #= require slender_data/parameterizable
4
+
5
+
6
+ # High-level SDK for CRUD operations against a BREST API.
7
+ #
8
+ # Takes arguments as Queries (SingleQuery or MultiQuery),
9
+ # and expects the server to return self-describing data in raw query form,
10
+ # i.e. as "user: {...}" instead of just "{...}" when returning a user object.
11
+ # The server responses are forwarded as-is to the callers.
12
+ class slender_data.BrestLoader extends slender_data.Parameterizable
13
+
14
+ constructor: (params) ->
15
+ super params
16
+
17
+ # The base url of the BREST API on the server.
18
+ #
19
+ # Example: provide '/api' to access users at '/api/users'.
20
+ @base_url = params.base_url or ''
21
+
22
+
23
+ # Creates the entry described by the given query on the server.
24
+ create: (entry, callback) ->
25
+ data = {}
26
+ data[@entry_name] = entry
27
+
28
+ jQuery.ajax
29
+ url: @entries_url()
30
+ type: 'POST'
31
+ data: data
32
+ success: callback
33
+
34
+
35
+ # Creates the entries described by the given multi-query on the server.
36
+ create_many: (entries, callback) ->
37
+ data = {}
38
+ data[@entries_name] = entries
39
+
40
+ jQuery.ajax
41
+ url: @entries_url()
42
+ type: 'POST'
43
+ data: data
44
+ success: callback
45
+
46
+
47
+ # Deletes the entry described by the given query on the server.
48
+ delete: (query, callback) ->
49
+ query = @_querify_single query
50
+ jQuery.ajax
51
+ url: @entry_url(query)
52
+ type: 'DELETE'
53
+ success: callback
54
+
55
+
56
+ # Deletes the entries described by the given multi-query on the server.
57
+ delete_many: (multi_query, callback) ->
58
+ multi_query = @_querify_multi multi_query
59
+ data = {}
60
+ data[@ids_name] = multi_query.ids()
61
+ jQuery.ajax
62
+ url: @entries_url()
63
+ type: 'DELETE'
64
+ data: data
65
+ success: callback
66
+
67
+
68
+ # Returns the url to access a single entry.
69
+ entry_url: (query) ->
70
+ query = @_querify_single query
71
+ "#{@base_url}/#{@entries_name}/#{query.id()}.json"
72
+
73
+
74
+ # Returns the url to access the collection of entries.
75
+ entries_url: ->
76
+ @_entries_url_result or= "#{@base_url}/#{@entries_name}.json"
77
+
78
+
79
+ # Merges the entries described by the given ids
80
+ # into a new entry with the given data.
81
+ merge: (old_entry_ids, new_entry, callback) ->
82
+ data =
83
+ old_snippet_ids: old_entry_ids
84
+ merged_snippet_data: new_entry
85
+ $.ajax
86
+ url: "#{@base_url}/#{@entries_name}/merge.json"
87
+ type: 'POST'
88
+ data: data
89
+ success: callback
90
+
91
+ # Fetches the entry with the given key from the server.
92
+ read: (query, callback) ->
93
+ query = @_querify_single query
94
+ jQuery.get @entry_url(query), callback
95
+
96
+
97
+ # Loads all objects from the server.
98
+ # Provides the given params as parameters to the GET request.
99
+ read_many: (multi_query, callback) ->
100
+ multi_query = @_querify_multi multi_query
101
+ data = {}
102
+ data[multi_query.ids_name] = multi_query.ids().join(' ')
103
+ jQuery.ajax
104
+ url: @entries_url()
105
+ type: 'GET'
106
+ cache: no
107
+ data: data
108
+ success: callback
109
+
110
+
111
+ # Updates the given entry on the server.
112
+ #
113
+ # The entry can be a partial diff of the real entry,
114
+ # but must contain the key column.
115
+ update: (entry, callback) ->
116
+ data = {}
117
+ data[@entry_name] = entry
118
+
119
+ jQuery.ajax
120
+ url: @entry_url(entry: entry)
121
+ type: 'PUT'
122
+ data: data
123
+ success: callback
124
+
125
+
126
+ # Updates the given entries on the server.
127
+ #
128
+ # The entry can be a partial diff of the real entry,
129
+ # but must contain the key column.
130
+ update_many: (entries, callback) ->
131
+ data = {}
132
+ data[@entries_name] = entries
133
+
134
+ jQuery.ajax
135
+ url: @entries_url()
136
+ type: 'PUT'
137
+ data: data
138
+ success: callback
139
+
@@ -1,5 +1,6 @@
1
1
  # A generic cache.
2
2
  # Stores key-value pairs.
3
+ # This is pretty much a more comfortable hash object.
3
4
  class slender_data.Cache
4
5
 
5
6
  constructor: ->
@@ -22,20 +23,18 @@ class slender_data.Cache
22
23
  # Looks up several entries at once.
23
24
  # Returns a hash of found entries, and a list of missing entries.
24
25
  get_many: (keys) ->
25
- result = { found: {}, missing: [] }
26
+ found = []
27
+ missing = []
26
28
  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
29
+ if (entry = @cache[key])
30
+ found.push entry
31
+ else
32
+ missing.push key
33
+ found: found, missing: missing
35
34
 
36
35
 
37
36
  # Returns the number of cached objects.
38
- length: () ->
37
+ length: ->
39
38
  slender_data.object_length @cache
40
39
 
41
40
 
@@ -47,17 +46,3 @@ class slender_data.Cache
47
46
  # Removes all entries with the given keys.
48
47
  remove_many: (keys) ->
49
48
  @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,107 @@
1
+ #= require slender_data/query_cache
2
+ #= require slender_data/queries/single_query
3
+ #= require slender_data/queries/multi_query
4
+ #= require slender_data/parameterizable
5
+
6
+
7
+ # Stores JSON data objects, and tracks changes to them.
8
+ class slender_data.EntryStore extends slender_data.Parameterizable
9
+
10
+ constructor: (params) ->
11
+ super params
12
+
13
+ # Unmodified copies of the serverside data.
14
+ @server_data = new slender_data.QueryCache params
15
+
16
+ # Replicas of the server data, to be modified by the client.
17
+ @client_data = new slender_data.QueryCache params
18
+
19
+
20
+ # Adds the given entry to the caches.
21
+ # Treats the given entry as coming from the server.
22
+ add: (entry) ->
23
+ @server_data.add entry
24
+ @client_data.remove entry
25
+
26
+ # Must return undefined, since we don't want to
27
+ # create the client entry yet to save memory and CPU,
28
+ # and the user should not be mislead by a returned server entry.
29
+ return
30
+
31
+
32
+ # Adds the given data objects to the server cache.
33
+ add_many: (entries) ->
34
+ @add(entry) for entry in entries
35
+ return # Should not return anything.
36
+
37
+
38
+ # Removes the entry corresponding to the given query
39
+ # from this DataStore.
40
+ delete: (entry) ->
41
+ @client_data.remove entry
42
+ @server_data.remove entry
43
+
44
+
45
+ # Removes the entries corresponding to the given multi-query
46
+ # from this DataStore.
47
+ delete_many: (entries) ->
48
+ @client_data.remove_many entries
49
+ @server_data.remove_many entries
50
+
51
+
52
+ # Returns an object that contains only the changed attributes
53
+ # of the entry destribed by the given query.
54
+ # Returns false if the entry is not changed.
55
+ entry_changes: (entry) ->
56
+ server_version = @server_data.get entry: entry
57
+ changes = slender_data.object_diff server_version, entry
58
+ if slender_data.object_length(changes) > 0
59
+ changes[@id_name] = entry[@id_name]
60
+ changes
61
+ else
62
+ false
63
+
64
+
65
+ # Returns an array containing only the changed objects.
66
+ # Each object contains only the changed columns + key column.
67
+ entries_changes: (entries) ->
68
+ result = []
69
+ for entry in entries
70
+ if (entry_changes = @entry_changes entry)
71
+ result.push entry_changes
72
+ result
73
+
74
+
75
+ # Returns the entry described by the given query,
76
+ # or undefined if it does not exist in any of the caches.
77
+ get: (query) ->
78
+ query = @_querify_single query
79
+
80
+ # Try to use client_data cache.
81
+ unless (result = @client_data.get query)
82
+
83
+ # No data in client cache --> try to use server cache.
84
+ if (server_entry = @server_data.get query)
85
+ result = @client_data.add_clone server_entry
86
+
87
+ result
88
+
89
+
90
+ # Returns the entries described by the given multi-query,
91
+ # as well as a list of entries not found.
92
+ get_many: (multi_query) ->
93
+ found = []
94
+
95
+ # Load client-side data.
96
+ client_results = @client_data.get_many @_querify_multi(multi_query)
97
+ $.merge found, client_results.found
98
+ missing_query = client_results.missing
99
+
100
+ if not missing_query.empty()
101
+ # Some entries not in client cache --> look in server cache.
102
+ server_results = @server_data.get_many missing_query
103
+ $.merge found, @client_data.add_clones(server_results.found)
104
+ missing_query = server_results.missing
105
+
106
+ found: found, missing: missing_query
107
+
@@ -0,0 +1,28 @@
1
+ # Fires events indicating whether a loading operation is currently happening or not.
2
+ class slender_data.LoadingIndicator
3
+
4
+ constructor: ->
5
+
6
+ # The number of currently running loading operations.
7
+ @loader_count = 0
8
+
9
+
10
+ # The different events that this class can fire.
11
+ @events =
12
+ AJAX_LOADING: 'AJAX_LOADING'
13
+ AJAX_LOADED: 'AJAX_LOADED'
14
+
15
+
16
+ # Lets this LoadingIndicator know that another loading operation has started.
17
+ loading_started: ->
18
+ @loader_count++
19
+ if @loader_count == 1
20
+ $('body').trigger slender_data.AjaxLoader.events.AJAX_LOADING
21
+
22
+
23
+ # Lets this LoadingIndicator know that a loading operation has finished.
24
+ loading_finished: ->
25
+ @loader_count--
26
+ if @loader_count == 0
27
+ $('body').trigger slender_data.AjaxLoader.events.AJAX_LOADED
28
+
@@ -0,0 +1,74 @@
1
+ #= require ../query/single_query
2
+ #= require ../query/multi_query
3
+
4
+
5
+ # Tracks which snippets are currently getting loaded,
6
+ # and manages requests for snippet data.
7
+ class sn.LoadingTracker
8
+
9
+ constructor: ->
10
+
11
+ # Maps currently loading snippets to callbacks waiting for their data.
12
+ # Key = snippet id, value = array of callbacks
13
+ @loading_snippets = {}
14
+
15
+
16
+ # Returns whether the snippet with the given id is currently loading.
17
+ is_loading: (query) ->
18
+ query = sn.SingleQuery.instancify query
19
+ console.log "LoadingTracker.is_loading: snippet #{query.id()} loading status: #{@loading_snippets[query.id()]?}"
20
+ @loading_snippets[query.id()]?
21
+
22
+
23
+ # Returns all ids within the requested ids that are currently loading.
24
+ matching_loading_ids: (requested_ids) ->
25
+ _.filter requested_ids, (requested_id) =>
26
+ @is_loading id: requested_id
27
+
28
+
29
+ # Notifies this LoadingTracker that the given snippet has arrived.
30
+ snippet_arrived: (snippet) ->
31
+ console.log "LoadingTracker: received snippet #{snippet.id}"
32
+
33
+ # Call the callbacks registered for the loaded snippet.
34
+ if (callbacks = @loading_snippets[snippet.id])
35
+ callback() for callback in callbacks
36
+
37
+ # Remove the id of the loaded snippet from the loading list.
38
+ delete @loading_snippets[snippet.id]
39
+
40
+
41
+ # Notifies this LoadingTracker that the given snippets have arrived.
42
+ snippets_arrived: (snippets) ->
43
+ console.log "LoadingTracker: received snippets #{(s.id for s in snippets).join '+'}"
44
+ @snippet_arrived(snippet) for snippet in snippets
45
+
46
+
47
+ # Registers the given snippet as currently loading from the server.
48
+ start_loading: (query) ->
49
+ query = sn.SingleQuery.instancify query
50
+ console.log "LoadingTracker: starting to load #{query.id()}"
51
+ @loading_snippets[query.id()] or= []
52
+
53
+
54
+ # Registers the given snippets as currently loading from the server.
55
+ start_loadings: (multi_query) ->
56
+ multi_query = sn.MultiQuery.instancify multi_query
57
+ console.log "LoadingTracker: starting to load multiple #{multi_query.ids()}"
58
+ @start_loading(query) for query in multi_query.transpose()
59
+
60
+
61
+ # Calls the given callback when the snippet with the given id is loaded.
62
+ wait_for_loading_finished: (query, callback) ->
63
+ query = sn.SingleQuery.instancify query
64
+
65
+ if @is_loading(query)
66
+ # Snippet is loading --> queue the callback until later.
67
+ console.log "LoadingTracker.wait_for_loading_finished: snippet #{query.id()} is loading, waiting for it"
68
+ @loading_snippets[query.id()].push callback
69
+ else
70
+ # Snippet is not loading --> return immediately.
71
+ console.log "LoadingTracker.wait_for_loading_finished: snippet #{query.id()} is not loading"
72
+ return callback()
73
+
74
+
@@ -0,0 +1,50 @@
1
+ # Base class for all classes that are configured by a SlenderData configuration object.
2
+ class slender_data.Parameterizable
3
+
4
+ constructor: (params) ->
5
+
6
+ # The name of a data entry,
7
+ # i.e. "user".
8
+ @entry_name = params.entry_name ? throw new Error('You must provide an entry name')
9
+
10
+ # Name of multiple data entries,
11
+ # i.e. "users".
12
+ @entries_name = params.entries_name ? "#{@entry_name}s"
13
+
14
+ # Name of the id field in entries.
15
+ @id_name = params.id_name ? 'id'
16
+
17
+ # Name of the ids field in entries.
18
+ @ids_name = params.ids_name ? "#{@id_name}s"
19
+
20
+ # The method to use to check whether a given entry is full or partial.
21
+ @is_full_entry = params.full_entry_checker
22
+
23
+ # The class that is used to represent multi-queries.
24
+ @multi_query_class = params.multi_query_class ? slender_data.MultiQuery
25
+
26
+ # The given parameters.
27
+ @params = params
28
+
29
+ # Whether partial entry supported is enabled.
30
+ @partial_entries = params.partial_entries ? no
31
+
32
+ # The class that is used to represent single queries.
33
+ @single_query_class = params.single_query_class ? slender_data.SingleQuery
34
+
35
+ # Name of the version attribute,
36
+ # i.e. "timestamp".
37
+ @version_name = params.version_name ? 'version'
38
+
39
+ # Whether versioning should be supported or not.
40
+ @versioning = params.versioning ? no
41
+
42
+
43
+ # Makes sure the given query is indeed a SingleQuery.
44
+ _querify_single: (query) ->
45
+ slender_data.querify query, @single_query_class, @params
46
+
47
+ # Makes sure the given query is indeed a MultiQuery.
48
+ _querify_multi: (multi_query) ->
49
+ slender_data.querify multi_query, @multi_query_class, @params
50
+