Unreviewed, rolling out r216677.
[WebKit-https.git] / PerformanceTests / Speedometer / resources / todomvc / dependency-examples / flight / bower_components / depot / depot.js
1 // depot.js v0.1.6
2
3 // (c) 2013 Michal Kuklis
4 // Licensed under The MIT License
5 // http://opensource.org/licenses/MIT
6
7 (function (name, root, factory) {
8   if (typeof exports == 'object') {
9     module.exports = factory();
10   } else if (typeof define == 'function' && define.amd) {
11     define(factory);
12   } else {
13     root[name] = factory();
14   }
15 }("depot", this, function () {
16
17   "use strict";
18
19   // depot api
20
21   var api = {
22
23     save: function (record) {
24       var id;
25
26       if (!record[this.idAttribute]) {
27         record[this.idAttribute] = guid();
28       }
29
30       id = record[this.idAttribute] + '';
31
32       if (this.ids.indexOf(id) < 0) {
33         this.ids.push(id);
34         this.storageAdaptor.setItem(this.name, this.ids.join(","));
35       }
36
37       this.storageAdaptor.setItem(getKey(this.name, id), JSON.stringify(record));
38
39       return record;
40     },
41
42     update: function (id, data) {
43       if (typeof data == 'undefined') {
44         data = id;
45         id = data[this.idAttribute];
46       }
47
48       var record = this.get(id);
49
50       if (record) {
51         record = extend(record, data);
52         this.save(record);
53       }
54
55       return record;
56     },
57
58     updateAll: function (data) {
59       var records = this.all();
60
61       records.forEach(function (record) {
62         record = extend(record, data);
63         this.save(record);
64       }, this);
65
66       return records;
67     },
68
69     find: function (criteria) {
70       var key, match, record;
71       var name = this.name;
72       var self = this;
73
74       if (!criteria) return this.all();
75
76       return this.ids.reduce(function (memo, id) {
77         record = jsonData(self.storageAdaptor.getItem(getKey(name, id)));
78         match = findMatch(criteria, record);
79
80         if (match) {
81           memo.push(record);
82         }
83
84         return memo;
85       }, []);
86     },
87
88     get: function (id) {
89       return jsonData(this.storageAdaptor.getItem(getKey(this.name, id)));
90     },
91
92     all: function () {
93       var record, self = this, name = this.name;
94
95       return this.ids.reduce(function (memo, id) {
96         record = self.storageAdaptor.getItem(getKey(name, id));
97
98         if (record) {
99           memo.push(jsonData(record));
100         }
101
102         return memo;
103       }, []);
104     },
105
106     destroy: function (record) {
107       var index;
108       var id = (record[this.idAttribute]) ? record[this.idAttribute] : record;
109       var key = getKey(this.name, id);
110
111       record = jsonData(this.storageAdaptor.getItem(key));
112       this.storageAdaptor.removeItem(key);
113
114       index = this.ids.indexOf(id);
115       if (index != -1) this.ids.splice(index, 1);
116       this.storageAdaptor.setItem(this.name, this.ids.join(","));
117
118       return record;
119     },
120
121     destroyAll: function (criteria) {
122       var attr, id, match, record, key;
123
124       for (var i = this.ids.length - 1; i >= 0; i--) {
125         id = this.ids[i];
126         key = getKey(this.name, id);
127
128         if (criteria) {
129
130           record = jsonData(this.storageAdaptor.getItem(key));
131           match = findMatch(criteria, record);
132
133           if (match) {
134             this.storageAdaptor.removeItem(key);
135             this.ids.splice(i, 1);
136           }
137
138         }
139         else {
140           this.storageAdaptor.removeItem(key);
141         }
142       }
143
144       if (criteria) {
145         this.storageAdaptor.setItem(this.name, this.ids.join(","));
146       }
147       else {
148         this.storageAdaptor.removeItem(this.name);
149         this.ids = [];
150       }
151     },
152
153     size: function () {
154       return this.ids.length;
155     }
156   };
157
158   // helpers
159
160   function jsonData(data) {
161     return data && JSON.parse(data);
162   }
163
164   function getKey(name, id) {
165     return name + "-" + id;
166   }
167
168   function findMatch(criteria, record) {
169     var match, attr;
170
171     if (typeof criteria == 'function') {
172       match = criteria(record);
173     }
174     else {
175       match = true;
176       for (attr in criteria) {
177         match &= (criteria[attr] === record[attr]);
178       }
179     }
180
181     return match;
182   }
183
184   function s4() {
185     return Math.floor((1 + Math.random()) * 0x10000)
186       .toString(16).substring(1);
187   }
188
189   function guid() {
190     return s4() + s4() + '-' + s4() + '-' + s4() +
191       '-' +s4() + '-' + s4() + s4() + s4();
192   }
193
194   function extend(dest, source) {
195     for (var key in source) {
196       if (source.hasOwnProperty(key)) {
197         dest[key] = source[key];
198       }
199     }
200
201     return dest;
202   }
203
204   function depot(name, options) {
205     var store, ids;
206
207     var data = {};
208     var localStorage = {
209         getItem: function (key) { return data[key]; },
210         setItem: function (key, value) {
211             if (!data[key])
212                 this.length++;
213             data[key] = value;
214         },
215         removeItem: function (key) {
216             delete data[key];
217             this.length--;
218         },
219         key: function (index) {
220             var i = 0;
221             for (var key in data) {
222                 if (i == index)
223                     return key;
224                 i++;
225             }
226             return null;
227         },
228         length: 0,
229     };
230
231     options = extend({
232       idAttribute: '_id',
233       storageAdaptor: localStorage
234     }, options);
235
236     if (!options.storageAdaptor) throw new Error("No storage adaptor was found");
237
238     store = options.storageAdaptor.getItem(name);
239     ids = (store && store.split(",")) || [];
240
241     return Object.create(api, {
242       name: { value: name },
243       store: { value: store },
244       ids: { value: ids, writable: true },
245       idAttribute: { value: options.idAttribute },
246       storageAdaptor: { value: options.storageAdaptor }
247     });
248   }
249
250   return depot;
251 }));