123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import { arrayToB64, isFile } from './utils';
- import OwnedFile from './ownedFile';
- class Mem {
- constructor() {
- this.items = new Map();
- }
- get length() {
- return this.items.size;
- }
- getItem(key) {
- return this.items.get(key);
- }
- setItem(key, value) {
- return this.items.set(key, value);
- }
- removeItem(key) {
- return this.items.delete(key);
- }
- key(i) {
- return this.items.keys()[i];
- }
- }
- class Storage {
- constructor() {
- try {
- this.engine = localStorage || new Mem();
- } catch (e) {
- this.engine = new Mem();
- }
- this._files = this.loadFiles();
- }
- loadFiles() {
- const fs = new Map();
- for (let i = 0; i < this.engine.length; i++) {
- const k = this.engine.key(i);
- if (isFile(k)) {
- try {
- const f = new OwnedFile(JSON.parse(this.engine.getItem(k)));
- if (!f.id) {
- f.id = f.fileId;
- }
- fs.set(f.id, f);
- } catch (err) {
- // obviously you're not a golfer
- this.engine.removeItem(k);
- }
- }
- }
- return fs;
- }
- get id() {
- let id = this.engine.getItem('device_id');
- if (!id) {
- id = arrayToB64(crypto.getRandomValues(new Uint8Array(16)));
- this.engine.setItem('device_id', id);
- }
- return id;
- }
- get totalDownloads() {
- return Number(this.engine.getItem('totalDownloads'));
- }
- set totalDownloads(n) {
- this.engine.setItem('totalDownloads', n);
- }
- get totalUploads() {
- return Number(this.engine.getItem('totalUploads'));
- }
- set totalUploads(n) {
- this.engine.setItem('totalUploads', n);
- }
- get referrer() {
- return this.engine.getItem('referrer');
- }
- set referrer(str) {
- this.engine.setItem('referrer', str);
- }
- get enrolled() {
- return JSON.parse(this.engine.getItem('ab_experiments') || '{}');
- }
- enroll(id, variant) {
- const enrolled = {};
- enrolled[id] = variant;
- this.engine.setItem('ab_experiments', JSON.stringify(enrolled));
- }
- get files() {
- return Array.from(this._files.values()).sort(
- (a, b) => a.createdAt - b.createdAt
- );
- }
- get user() {
- try {
- return JSON.parse(this.engine.getItem('user'));
- } catch (e) {
- return null;
- }
- }
- set user(info) {
- return this.engine.setItem('user', JSON.stringify(info));
- }
- getFileById(id) {
- return this._files.get(id);
- }
- get(id) {
- return this.engine.getItem(id);
- }
- set(id, value) {
- return this.engine.setItem(id, value);
- }
- remove(property) {
- if (isFile(property)) {
- this._files.delete(property);
- }
- this.engine.removeItem(property);
- }
- addFile(file) {
- this._files.set(file.id, file);
- this.writeFile(file);
- }
- writeFile(file) {
- this.engine.setItem(file.id, JSON.stringify(file));
- }
- writeFiles() {
- this._files.forEach(f => this.writeFile(f));
- }
- clearLocalFiles() {
- this._files.forEach(f => this.engine.removeItem(f.id));
- this._files = new Map();
- }
- async merge(files = []) {
- let incoming = false;
- let outgoing = false;
- let downloadCount = false;
- for (const f of files) {
- if (!this.getFileById(f.id)) {
- this.addFile(new OwnedFile(f));
- incoming = true;
- }
- }
- const workingFiles = this.files.slice();
- for (const f of workingFiles) {
- const cc = await f.updateDownloadCount();
- if (cc) {
- await this.writeFile(f);
- }
- downloadCount = downloadCount || cc;
- outgoing = outgoing || f.expired;
- if (f.expired) {
- this.remove(f.id);
- } else if (!files.find(x => x.id === f.id)) {
- outgoing = true;
- }
- }
- return {
- incoming,
- outgoing,
- downloadCount
- };
- }
- }
- export default new Storage();
|