From 11abd6170b7affc1b3217e27a1df31e1ccf17e24 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 6 Nov 2020 15:30:56 +0100 Subject: [PATCH] Use indexeddb cache for blobs --- www/common/media-tag.js | 70 +++++++++++++++++++++++++-------- www/common/outer/cache-store.js | 22 +++++++++++ 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/www/common/media-tag.js b/www/common/media-tag.js index 27683c54e..1d7cd0c61 100644 --- a/www/common/media-tag.js +++ b/www/common/media-tag.js @@ -1,8 +1,5 @@ -(function(name, definition) { - if (typeof module !== 'undefined') { module.exports = definition(); } - else if (typeof define === 'function' && typeof define.amd === 'object') { define(definition); } - else { this[name] = definition(); } -}('MediaTag', function() { +(function (window) { +var factory = function (Cache) { var cache; var cypherChunkLength = 131088; @@ -133,20 +130,44 @@ cb = function () {}; }; - var xhr = new XMLHttpRequest(); - xhr.open('GET', src, true); - xhr.responseType = 'arraybuffer'; - - xhr.onerror = function () { return void cb("XHR_ERROR"); }; - xhr.onload = function () { - // Error? - if (/^4/.test('' + this.status)) { return void cb("XHR_ERROR " + this.status); } + var _src = src.replace(/(\/)*$/, ''); // Remove trailing slashes + var idx = _src.lastIndexOf('/'); + var cacheKey = _src.slice(idx+1); + if (!/^[a-f0-9]{48}$/.test(cacheKey)) { cacheKey = undefined; } + + var fetch = function () { + var xhr = new XMLHttpRequest(); + xhr.open('GET', src, true); + xhr.responseType = 'arraybuffer'; + + xhr.onerror = function () { return void cb("XHR_ERROR"); }; + xhr.onload = function () { + // Error? + if (/^4/.test('' + this.status)) { return void cb("XHR_ERROR " + this.status); } + + var arrayBuffer = xhr.response; + if (arrayBuffer) { + var u8 = new Uint8Array(arrayBuffer); + if (cacheKey) { + return void Cache.setBlobCache(cacheKey, u8, function (err) { + cb(null, u8); + }); + } + cb(null, u8); + } + }; - var arrayBuffer = xhr.response; - if (arrayBuffer) { cb(null, new Uint8Array(arrayBuffer)); } + xhr.send(null); }; - xhr.send(null); + if (!cacheKey) { return void fetch(); } + + Cache.getBlobCache(cacheKey, function (err, u8) { + if (err || !u8) { return void fetch(); } + console.error('using cache', cacheKey); + cb(null, u8); + }); + }; // Decryption tools @@ -469,4 +490,19 @@ }; return init; -})); +}; + + if (typeof(module) !== 'undefined' && module.exports) { + module.exports = factory( + require("./outer/cache-store.js") + ); + } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { + define([ + '/common/outer/cache-store.js', + ], function (Cache) { + return factory(Cache); + }); + } else { + // unsupported initialization + } +}(typeof(window) !== 'undefined'? window : {})); diff --git a/www/common/outer/cache-store.js b/www/common/outer/cache-store.js index ff2a40e93..fe3b541b2 100644 --- a/www/common/outer/cache-store.js +++ b/www/common/outer/cache-store.js @@ -8,6 +8,28 @@ define([ name: "cp_cache" }); + S.getBlobCache = function (id, cb) { + cb = Util.once(Util.mkAsync(cb || function () {})); + cache.getItem(id, function (err, obj) { + if (err || !obj || !obj.c) { + return void cb(err || 'EINVAL'); + } + cb(null, obj.c); + obj.t = +new Date(); + cache.setItem(id, obj); + }); + }; + S.setBlobCache = function (id, u8, cb) { + cb = Util.once(Util.mkAsync(cb || function () {})); + if (!u8) { return void cb('EINVAL'); } + cache.setItem(id, { + c: u8, + t: (+new Date()) // 't' represent the "lastAccess" of this cache (get or set) + }, function (err) { + cb(err); + }); + }; + // id: channel ID or blob ID // returns array of messages S.getChannelCache = function (id, cb) {