UNPKG

27.1 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _typeof2 = require('babel-runtime/helpers/typeof');
8
9var _typeof3 = _interopRequireDefault(_typeof2);
10
11var _keys = require('babel-runtime/core-js/object/keys');
12
13var _keys2 = _interopRequireDefault(_keys);
14
15var _regenerator = require('babel-runtime/regenerator');
16
17var _regenerator2 = _interopRequireDefault(_regenerator);
18
19var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
20
21var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
22
23exports.default = setupCache;
24
25var _pouchdb = require('pouchdb');
26
27var _pouchdb2 = _interopRequireDefault(_pouchdb);
28
29function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30
31var Promise = require('bluebird');
32
33var url = require('url');
34var _ = require('lodash');
35var pointer = require('json-pointer');
36
37//TODO: Should getLookup throw an error or return undefined?
38// This needs to be handled by all that call getLookup!!!
39
40
41function setupCache(_ref) {
42
43 // Accepts an axios-style request. Returns:
44 // {
45 //
46 // data: the data requested,
47 //
48 // _rev: the rev of the parent resource requested
49 //
50 // location: e.g.: /resources/abc123/some/path/leftover
51 //
52 // }
53 var get = function () {
54 var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(req) {
55 var urlObj, lookup;
56 return _regenerator2.default.wrap(function _callee$(_context) {
57 while (1) {
58 switch (_context.prev = _context.next) {
59 case 0:
60 urlObj = url.parse(req.url);
61
62 if (/^\/resources/.test(urlObj.path)) {
63 _context.next = 12;
64 break;
65 }
66
67 _context.prev = 2;
68 _context.next = 5;
69 return getLookup(req);
70
71 case 5:
72 lookup = _context.sent;
73
74 req.url = urlObj.protocol + '//' + urlObj.host + '/' + lookup.doc.resourceId + lookup.doc.pathLeftover;
75 _context.next = 12;
76 break;
77
78 case 9:
79 _context.prev = 9;
80 _context.t0 = _context['catch'](2);
81 throw _context.t0;
82
83 case 12:
84 return _context.abrupt('return', getResFromDb(req).then(function (result) {
85 return result;
86 }));
87
88 case 13:
89 case 'end':
90 return _context.stop();
91 }
92 }
93 }, _callee, this, [[2, 9]]);
94 }));
95
96 return function get(_x) {
97 return _ref2.apply(this, arguments);
98 };
99 }();
100
101 // Perform lookup from bookmarks to resource id (and path leftover) mapping.
102 // If the lookup fails, use a HEAD request to get it from the server and put
103 // it in the cache. An optional _id can be passed into req to force creation
104 // of a particular lookup in the even that the resource doesn't yet exist but _will_.
105 // This is primarily for when links are created before the resource itself has been.
106
107
108 /* async function _recursivePut(req) {
109 let urlObj = url.parse(req.url);
110 return Promise.map(Object.keys(req.data || {}), (data) => {
111 var newData = replaceLinks(data, req)
112 })
113 if (body._rev) {
114 let lookup = await getLookup({
115 url: req.url,
116 headers: req.headers,
117 _id: body._id
118 })
119 let newBody = replaceLinks(body, {
120 url: req.url,
121 headers: req.headers
122 });
123 await dbUpsert({
124 url: urlObj.protocol+'//'+urlObj.host+'/'+(body._id || lookup.doc.resourceId),
125 headers: req.headers
126 }, {
127 data: newBody,
128 headers: { 'x-oada-rev': newBody._rev },
129 })
130 }
131 if (typeof body === 'object') {
132 return Promise.map(Object.keys(body || {}), (key) => {
133 if (key.charAt(0) === '_') return
134 if (!body[key]) return
135 return _recursiveUpsert({
136 url: req.url+'/'+key,
137 headers: req.headers
138 }, body[key])
139 })
140 } else return
141 }*/
142
143 var deleteCheckParent = function () {
144 var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(req, res) {
145 var urlObj, _rev, lookup, reqPieces, parentUrl;
146
147 return _regenerator2.default.wrap(function _callee2$(_context2) {
148 while (1) {
149 switch (_context2.prev = _context2.next) {
150 case 0:
151 urlObj = url.parse(req.url);
152 _rev = res.headers['x-oada-rev'];
153 lookup = void 0;
154 // Try to get the parent document
155
156 _context2.prev = 3;
157 reqPieces = urlObj.path.split('/');
158 _context2.next = 7;
159 return getLookup({
160 url: urlObj.protocol + '//' + urlObj.host + reqPieces.slice(0, reqPieces.length - 1).join('/'),
161 headers: req.headers
162 });
163
164 case 7:
165 lookup = _context2.sent;
166
167 if (!(lookup && lookup.doc.resourceId)) {
168 _context2.next = 11;
169 break;
170 }
171
172 parentUrl = urlObj.protocol + '//' + urlObj.host + '/' + lookup.doc.resourceId + lookup.doc.pathLeftover;
173 return _context2.abrupt('return', dbUpsert({
174 url: parentUrl,
175 headers: req.headers,
176 method: req.method
177 }, {
178 data: undefined,
179 _valid: false,
180 headers: { 'x-oada-rev': _rev }
181 }));
182
183 case 11:
184 return _context2.abrupt('return');
185
186 case 14:
187 _context2.prev = 14;
188 _context2.t0 = _context2['catch'](3);
189 throw _context2.t0;
190
191 case 17:
192 case 'end':
193 return _context2.stop();
194 }
195 }
196 }, _callee2, this, [[3, 14]]);
197 }));
198
199 return function deleteCheckParent(_x2, _x3) {
200 return _ref3.apply(this, arguments);
201 };
202 }();
203
204 // ALTERNATIVELY, using db.remove:
205 // 1. Delete at server
206 // If no pathLeftover
207 // 2a. Invalidate parent
208 // 3a. Invalidate child
209 // 4a. GET parent from server to cache the new, unlinked data
210 // If pathleftover
211 // 2b. GET the child to confirm and cache the new state
212
213
214 var dbDelete = function () {
215 var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(req, res) {
216 var urlObj, _rev, pieces, resourceId, pathLeftover, lookup;
217
218 return _regenerator2.default.wrap(function _callee3$(_context3) {
219 while (1) {
220 switch (_context3.prev = _context3.next) {
221 case 0:
222 urlObj = url.parse(req.url);
223 _rev = res.headers['x-oada-rev'];
224 pieces = res.headers['content-location'].split('/');
225 resourceId = pieces.slice(1, 3).join('/'); //returns resources/abc
226
227 pathLeftover = pieces.length > 3 ? '/' + pieces.slice(3, pieces.length).join('/') : '';
228 // If it is itself a resource, we only need to invalidate the cache entry for
229 // the parent (which links to the child)
230
231 _context3.prev = 5;
232 _context3.next = 8;
233 return getLookup({
234 url: req.url,
235 headers: req.headers
236 });
237
238 case 8:
239 lookup = _context3.sent;
240 _context3.next = 11;
241 return db.remove(lookup);
242
243 case 11:
244 _context3.next = 15;
245 break;
246
247 case 13:
248 _context3.prev = 13;
249 _context3.t0 = _context3['catch'](5);
250
251 case 15:
252 if (pathLeftover) {
253 _context3.next = 17;
254 break;
255 }
256
257 return _context3.abrupt('return', deleteCheckParent(req, res));
258
259 case 17:
260 return _context3.abrupt('return', dbUpsert({
261 url: urlObj.protocol + '//' + urlObj.host + '/' + resourceId,
262 headers: req.headers,
263 method: req.method
264 }, {
265 data: undefined,
266 _valid: false,
267 headers: { 'x-oada-rev': _rev }
268 }));
269
270 case 18:
271 case 'end':
272 return _context3.stop();
273 }
274 }
275 }, _callee3, this, [[5, 13]]);
276 }));
277
278 return function dbDelete(_x4, _x5) {
279 return _ref4.apply(this, arguments);
280 };
281 }();
282
283 // Issue DELETE to server then update the db
284
285
286 var _recursiveUpsert = function () {
287 var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(req, body) {
288 var urlObj, lookup, newBody;
289 return _regenerator2.default.wrap(function _callee5$(_context5) {
290 while (1) {
291 switch (_context5.prev = _context5.next) {
292 case 0:
293 urlObj = url.parse(req.url);
294
295 if (!body._rev) {
296 _context5.next = 8;
297 break;
298 }
299
300 _context5.next = 4;
301 return getLookup({
302 url: req.url,
303 headers: req.headers,
304 _id: body._id
305 });
306
307 case 4:
308 lookup = _context5.sent;
309 newBody = replaceLinks(body, {
310 url: req.url,
311 headers: req.headers
312 });
313 _context5.next = 8;
314 return dbUpsert({
315 url: urlObj.protocol + '//' + urlObj.host + '/' + (body._id || lookup.doc.resourceId),
316 headers: req.headers
317 }, {
318 data: newBody,
319 headers: { 'x-oada-rev': newBody._rev }
320 });
321
322 case 8:
323 if (!((typeof body === 'undefined' ? 'undefined' : (0, _typeof3.default)(body)) === 'object')) {
324 _context5.next = 12;
325 break;
326 }
327
328 return _context5.abrupt('return', Promise.map((0, _keys2.default)(body || {}), function (key) {
329 if (key.charAt(0) === '_') return;
330 if (!body[key]) return;
331 return _recursiveUpsert({
332 url: req.url + '/' + key,
333 headers: req.headers
334 }, body[key]);
335 }));
336
337 case 12:
338 return _context5.abrupt('return');
339
340 case 13:
341 case 'end':
342 return _context5.stop();
343 }
344 }
345 }, _callee5, this);
346 }));
347
348 return function _recursiveUpsert(_x8, _x9) {
349 return _ref6.apply(this, arguments);
350 };
351 }();
352
353 var resetCache = function () {
354 var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7() {
355 return _regenerator2.default.wrap(function _callee7$(_context7) {
356 while (1) {
357 switch (_context7.prev = _context7.next) {
358 case 0:
359 if (!db) {
360 _context7.next = 3;
361 break;
362 }
363
364 _context7.next = 3;
365 return db.destroy();
366
367 case 3:
368 db = undefined;
369 request = undefined;
370 expiration = undefined;
371
372 case 6:
373 case 'end':
374 return _context7.stop();
375 }
376 }
377 }, _callee7, this);
378 }));
379
380 return function resetCache() {
381 return _ref8.apply(this, arguments);
382 };
383 }();
384
385 var name = _ref.name,
386 req = _ref.req,
387 exp = _ref.exp;
388
389
390 // name should be made unique across domains and users
391 var db = db || new _pouchdb2.default(name);
392 var request = req;
393 var expiration = exp || 1000 * 60 * 60 * 24 * 2; //(ms/s)*(s/min)*(min/hr)*(hr/days)*days
394
395 // Get the resource and merge data if its already in the db.
396 function getUpsertDoc(req, res) {
397 var urlObj = url.parse(req.url);
398 var pieces = urlObj.path.split('/');
399 var resourceId = pieces.slice(1, 3).join('/'); //returns resources/abc
400 var pathLeftover = pieces.length > 3 ? '/' + pieces.slice(3, pieces.length).join('/') : '';
401 var dbPut = {
402 _id: resourceId,
403 doc: {
404 _valid: res._valid === undefined ? true : res._valid,
405 _accessed: Date.now()
406 }
407 // ALL updates to existing docs (upserts) need to supply the current _rev.
408 };return db.get(resourceId).then(function (result) {
409 //If theres a path leftover, create an empty object, add a key to warn users
410 //that the data is incomplete, and put the data at that path Leftover
411 if (result.doc._NOT_COMPLETE_RESOURCE) dbPut.doc._NOT_COMPLETE_RESOURCE = true;
412 dbPut._rev = result._rev;
413 // If a falsey _valid value is given, return the invalidated resource.
414 if (dbPut.doc._valid !== undefined && !dbPut.doc._valid) {
415 return Promise.resolve(dbPut);
416 }
417 if (req.method && req.method.toLowerCase() === 'delete') {
418 dbPut.doc.doc = dbPut.doc.doc || {};
419 req.url = urlObj.protocol + '//' + urlObj.host + '/' + resourceId;
420 } else {
421 if (pathLeftover) {
422 // merge the new data into the old at the path leftover, then return old
423 var curData = {};
424 try {
425 // If the path doesn't exist in the db doc, make an empty object.
426 curData = pointer.get(result.doc.doc, pathLeftover);
427 } catch (err) {}
428 var newData = _.merge(curData, res.data || {});
429 pointer.set(result.doc.doc, pathLeftover, newData);
430 dbPut.doc.doc = result.doc.doc;
431 } else dbPut.doc.doc = _.merge(result.doc.doc, res.data || {});
432 }
433 return dbPut;
434 }).catch(function (e) {
435 // Else, resource was not in the db.
436 //console.log(e)
437 if (req.method && req.method.toLowerCase() === 'delete') {
438 // Deleting a resource that doesn't exist: do nothing.
439 } else {
440 if (pathLeftover) {
441 //Execute the PUT and Warn users that the data is incomplete
442 var doc = {};
443 dbPut.doc._NOT_COMPLETE_RESOURCE = true;
444 pointer.set(doc, pathLeftover, _.clone(res.data));
445 dbPut.doc.doc = doc;
446 } else dbPut.doc.doc = res.data;
447 }
448 return dbPut;
449 });
450 }
451
452 function dbUpsert(req, res) {
453 return getUpsertDoc(req, res).then(function (dbPut) {
454 return db.put(dbPut) /*.then((result) => {
455 req.method = 'get';
456 console.log('regetting', req, res)
457 return getResFromDb(req, res)
458 })*/.catch(function (err) {
459 if (err.name === 'conflict') {
460 //TODO: avoid infinite loops with this type of call
461 // If there is a conflict in the lookup, repeat the lookup (the HEAD
462 // request likely took too long and the lookup was already created by
463 // another simultaneous request
464 return dbUpsert(req, res);
465 }
466 throw err;
467 });
468 });
469 }
470
471 function getResFromServer(req) {
472 return request({
473 method: 'GET',
474 url: req.url,
475 headers: req.headers
476 }).then(function (res) {
477 res.cached = false;
478 return dbUpsert(req, res).then(function () {
479 return res;
480 });
481 }).catch(function (err) {
482 throw err;
483 });
484 }
485
486 function getResFromDb(req, res) {
487 var urlObj = url.parse(req.url);
488 var pieces = urlObj.path.split('/');
489 var resourceId = pieces.slice(1, 3).join('/'); //returns resources/abc
490 var pathLeftover = pieces.length > 3 ? '/' + pieces.slice(3, pieces.length).join('/') : '';
491 return db.get(resourceId).then(function (resource) {
492 if (resource.doc._accessed + expiration <= Date.now() || !resource.doc._valid) {
493 return getResFromServer(req);
494 }
495 //If no pathLeftover, it'll just return resource!
496 return Promise.try(function () {
497 var data = pointer.get(resource.doc.doc, pathLeftover);
498 return {
499 data: data,
500 headers: {
501 'x-oada-rev': data._rev,
502 'content-location': resourceId + pathLeftover
503 },
504 status: 200,
505 cached: res ? res.cached : true
506 };
507 });
508 }).catch(function (err) {
509 //console.log(err);
510 return getResFromServer(req);
511 });
512 }function getLookup(req) {
513 var urlObj = url.parse(req.url);
514 var lookup = urlObj.host + urlObj.path;
515 return db.get(lookup).catch(function () {
516 //Not found. Go to the oada server, get the associated resource and path
517 //leftover, and save the lookup.
518 return request({
519 method: 'HEAD',
520 url: req.url,
521 headers: req.headers
522 }).then(function (response) {
523 //Save the url lookup for future use
524 var pieces = response.headers['content-location'].split('/');
525 var resourceId = pieces.slice(1, 3).join('/'); //returns resources/abc
526 var pathLeftover = pieces.length > 3 ? '/' + pieces.slice(3, pieces.length).join('/') : '';
527 if (req._id) {
528 resourceId = req._id;
529 pathLeftover = '';
530 }
531 return db.put({
532 _id: urlObj.host + urlObj.path,
533 doc: {
534 resourceId: resourceId,
535 pathLeftover: pathLeftover
536 }
537 }).then(function () {
538 return getLookup(req);
539 }).catch(function (err) {
540 console.log('ERR');
541 //TODO: avoid an infinite loop
542 if (err.name === 'conflict') {
543 // If there is a conflict in the lookup, repeat the lookup (the HEAD
544 // request likely took too long and the lookup was already created by
545 // another simultaneous request
546 return getLookup(req);
547 }
548 });
549 });
550 });
551 }
552
553 // Ping for _rev update
554 function checkChanges(req) {
555 return request({
556 method: 'HEAD',
557 url: req.url,
558 headers: req.headers
559 }).then(function () {
560 //compare to rev on hand
561 });
562 }
563
564 // Create a queue of actual PUTs to make when online.
565 // Resource breaks are known via setupTree.
566 // Do the puts, save out the resource IDs, and return to client
567 // Create an index on the data to find those that need synced
568
569 // Create a service that other apps can run which starts up and periodically
570 // checks if a connections has yet been made. A periodic service may also
571 // concievably check for updates to cached things.
572 //
573 // The cache should go "stale" after some period of time; However, if it cannot
574 // establish a connection, it should remain valid, usable data.
575
576
577 //TODO: First, get the _rev of the document to check against when the new rev
578 // is determined. Also, this function should compensate for a slow return time
579 // from the PUT operation; it should repeat the GET process until it finds a new
580 // _rev.
581
582
583 // TODO: Need to update the cache for both the parent resource and child new
584 // resource if one is created
585 function put(req) {
586 var urlObj = url.parse(req.url);
587 return request(req).then(function (response) {
588 var _rev = response.headers['x-oada-rev'];
589 var pieces = response.headers['content-location'].split('/');
590 var resourceId = pieces.slice(1, 3).join('/'); //returns resources/abc
591 var pathLeftover = pieces.length > 3 ? '/' + pieces.slice(3, pieces.length).join('/') : '';
592 // Invalidate the resource in the cache (if it is cached)
593 return dbUpsert({
594 url: urlObj.protocol + '//' + urlObj.host + '/' + resourceId,
595 headers: req.headers
596 }, {
597 data: undefined,
598 _valid: false,
599 headers: { 'x-oada-rev': _rev }
600 }).then(function () {
601 // Now get the data to bring it back into the cache. While dbUpsert does
602 // much of this, the lookup has not necessarily been created yet.
603 return get({
604 headers: req.headers,
605 url: urlObj.protocol + '//' + urlObj.host + '/' + resourceId,
606 //url: urlObj.protocol+'//'+urlObj.host+'/'+resourceId+pathLeftover,
607 method: 'get'
608 }).then(function () {
609 return response;
610 });
611 });
612 });
613 }function del(req) {
614 var urlObj = url.parse(req.url);
615 return request(req).then(function (response) {
616 return dbDelete(req, response).then(function () {
617 //it should return something that looks like a delete response
618 return response;
619 });
620 }).catch(function (e) {
621 // Handle offline case
622 throw e;
623 });
624 }
625
626 function replaceLinks(obj, req) {
627 var ret = Array.isArray(obj) ? [] : {};
628 if (!obj) return obj;
629 (0, _keys2.default)(obj || {}).forEach(function () {
630 var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(key, i) {
631 var val, lookup;
632 return _regenerator2.default.wrap(function _callee4$(_context4) {
633 while (1) {
634 switch (_context4.prev = _context4.next) {
635 case 0:
636 val = obj[key];
637
638 if (!((typeof val === 'undefined' ? 'undefined' : (0, _typeof3.default)(val)) !== 'object' || !val)) {
639 _context4.next = 4;
640 break;
641 }
642
643 ret[key] = val; // keep it asntType: 'application/vnd.oada.harvest.1+json'
644 return _context4.abrupt('return');
645
646 case 4:
647 if (!val._meta) {
648 _context4.next = 11;
649 break;
650 }
651
652 _context4.next = 7;
653 return getLookup({
654 url: req.url + '/' + key,
655 headers: req.headers
656 });
657
658 case 7:
659 lookup = _context4.sent;
660
661 ret[key] = { _id: lookup.doc.resourceId };
662 if (obj[key]._rev) ret[key]._rev = obj[key]._rev;
663 return _context4.abrupt('return');
664
665 case 11:
666 ret[key] = replaceLinks(obj[key], {
667 url: req.url + '/' + key,
668 headers: req.headers
669 }); // otherwise, recurse into the object
670
671 case 12:
672 case 'end':
673 return _context4.stop();
674 }
675 }
676 }, _callee4, this);
677 }));
678
679 return function (_x6, _x7) {
680 return _ref5.apply(this, arguments);
681 };
682 }());
683 return ret;
684 }
685
686 function findNullValue(obj, path, nullPath) {
687 if ((typeof obj === 'undefined' ? 'undefined' : (0, _typeof3.default)(obj)) === 'object') {
688 return Promise.map((0, _keys2.default)(obj || {}), function (key) {
689 if (obj[key] === null) {
690 nullPath = path + '/' + key;
691 return nullPath;
692 }
693 return findNullValue(obj[key], path + '/' + key, nullPath).then(function (res) {
694 nullPath = res || nullPath;
695 return res || nullPath;
696 });
697 }).then(function () {
698 return nullPath;
699 });
700 } else return Promise.resolve(undefined);
701 }
702
703 // Will this handle watches put on keys of a resource? i.e., no _id to be found
704 function findDeepestResource(obj, path, deepestResource) {
705 if ((typeof obj === 'undefined' ? 'undefined' : (0, _typeof3.default)(obj)) === 'object') {
706 return Promise.map((0, _keys2.default)(obj || {}), function (key) {
707 // _rev updates guaranteed to be present in change docs for affected resources
708 if (key === '_rev') {
709 deepestResource.path = path;
710 deepestResource.data = obj;
711 } else if (key.charAt(0) === '_') return deepestResource;
712 return findDeepestResource(obj[key], path + '/' + key, deepestResource).then(function () {
713 return deepestResource;
714 });
715 }).then(function () {
716 return deepestResource;
717 });
718 }
719 return Promise.resolve(deepestResource);
720 }
721
722 function handleWatchChange(payload) {
723 var _this = this;
724
725 var urlObj = url.parse(payload.request.url);
726 // Give the change body an _id so the deepest resource can be found
727 payload.response.change.body._id = payload.response.resourceId;
728 return findDeepestResource(payload.response.change.body, '', {
729 path: '',
730 data: payload.response.change.body
731 }).then(function () {
732 var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(deepestResource) {
733 var nullPath, deletedPath, lookup;
734 return _regenerator2.default.wrap(function _callee6$(_context6) {
735 while (1) {
736 switch (_context6.prev = _context6.next) {
737 case 0:
738 _context6.t0 = payload.response.change.type.toLowerCase();
739 _context6.next = _context6.t0 === 'delete' ? 3 : _context6.t0 === 'merge' ? 13 : 15;
740 break;
741
742 case 3:
743 _context6.next = 5;
744 return findNullValue(deepestResource.data, '', '');
745
746 case 5:
747 nullPath = _context6.sent;
748 deletedPath = deepestResource.path + nullPath;
749
750 payload.nullPath = deletedPath;
751 _context6.next = 10;
752 return getLookup({
753 url: payload.request.url + deepestResource.path + nullPath,
754 header: payload.request.headers
755 });
756
757 case 10:
758 lookup = _context6.sent;
759 return _context6.abrupt('return', dbDelete({
760 url: payload.request.url + deepestResource.path + nullPath,
761 headers: payload.request.headers,
762 method: payload.response.change.type
763 }, {
764 headers: {
765 'x-oada-rev': deepestResource.data._rev,
766 'content-location': '/' + lookup.doc.resourceId
767 }
768 }).then(function () {
769 // Update revs on all parents all the way down to (BUT OMITTING) the
770 // resource on which was the delete was called.
771 pointer.remove(payload.response.change.body, deepestResource.path || '/');
772 return _recursiveUpsert(payload.request, payload.response.change.body);
773 }));
774
775 case 13:
776 return _context6.abrupt('return', _recursiveUpsert(payload.request, payload.response.change.body));
777
778 case 15:
779 return _context6.abrupt('return');
780
781 case 16:
782 case 'end':
783 return _context6.stop();
784 }
785 }
786 }, _callee6, _this);
787 }));
788
789 return function (_x10) {
790 return _ref7.apply(this, arguments);
791 };
792 }()).catch(function (err) {
793 return;
794 });
795 }
796
797 var api = function handleRequest(req) {
798 switch (req.method) {
799 case 'get':
800 return get(req);
801 case 'delete':
802 return del(req);
803 case 'put':
804 return put(req);
805 }
806 };
807
808 return {
809 api: api,
810 db: db,
811 resetCache: resetCache,
812 handleWatchChange: handleWatchChange
813 };
814}
\No newline at end of file