browser-build.js 14 KB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var events = require('events');
var rxjs = require('rxjs');

function __extends(d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

var ElectronFileHandler = (function () {
    function ElectronFileHandler(ipcRenderer) {
        this.ipcRenderer = ipcRenderer;
    }
    ElectronFileHandler.prototype.download = function (source, target) {
        var _this = this;
        return rxjs.Observable.create(function (subscriber) {
            _this.ipcRenderer.once('bsync-download-complete', function () {
                _this.ipcRenderer.removeAllListeners('bsync-download-progress');
                _this.ipcRenderer.removeAllListeners('bsync-download-error');
                subscriber.complete();
            });
            _this.ipcRenderer.on('bsync-download-progress', function (progress) {
                subscriber.next(progress);
            });
            _this.ipcRenderer.once('bsync-download-error', function (error) {
                _this.ipcRenderer.removeAllListeners('bsync-download-progress');
                _this.ipcRenderer.removeAllListeners('bsync-download-complete');
                subscriber.error(error);
            });
            _this.ipcRenderer.send('bsync-download', {
                source: source,
                target: target
            });
        });
    };
    return ElectronFileHandler;
}());

var CordovaDownloader = (function () {
    function CordovaDownloader() {
    }
    CordovaDownloader.prototype.download = function (source, target) {
        return Rx.Observable.create(function (subscriber) {
            if (!window['FileTransfer']) {
                subscriber.error("Cordova FileTransfer object undefined");
            }
            var fileTransfer = new window['FileTransfer']();
            fileTransfer.onprogress = function (progress) {
                subscriber.next(progress.loaded / progress.total);
            };
            fileTransfer.download(source, target, function (entry) {
                subscriber.complete();
            }, function (error) {
                subscriber.error(error);
            }, true);
        });
    };
    return CordovaDownloader;
}());

var Util = (function () {
    function Util() {
    }
    Util.getNameHash = function (path) {
        for (var r = 0, i = 0; i < path.length; i++) {
            r = (r << 5) - r + path.charCodeAt(i), r &= r;
        }
        return "bsync_" + Math.abs(r);
    };
    return Util;
}());

var FileReplicator = (function (_super) {
    __extends(FileReplicator, _super);
    function FileReplicator() {
        _super.call(this);
        this._files = [];
        this._itemValidator = null;
        this._fileHandler = null;
        this._retryTimeout = 0;
        this._itemKey = "type";
        this._itemValue = "asset";
        this._itemSourceAttribute = "source";
        this._itemTargetAttribute = "target";
    }
    Object.defineProperty(FileReplicator.prototype, "files", {
        get: function () {
            return this._files;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "fileHandler", {
        set: function (handler) {
            this._fileHandler = handler;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "retryTimeout", {
        set: function (timeout) {
            this._retryTimeout = timeout;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "itemValidator", {
        set: function (validator) {
            this._itemValidator = validator;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "itemKey", {
        get: function () {
            return this._itemKey;
        },
        set: function (key) {
            this._itemKey = key;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "itemValue", {
        get: function () {
            return this._itemValue;
        },
        set: function (value) {
            this._itemValue = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "itemSourceAttribute", {
        get: function () {
            return this._itemSourceAttribute;
        },
        set: function (sourceAttribute) {
            this._itemSourceAttribute = sourceAttribute;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FileReplicator.prototype, "itemTargetAttribute", {
        get: function () {
            return this._itemTargetAttribute;
        },
        set: function (targetAttribute) {
            this._itemTargetAttribute = targetAttribute;
        },
        enumerable: true,
        configurable: true
    });
    FileReplicator.prototype.init = function (files) {
        if (files === void 0) { files = []; }
        this._files = files;
    };
    /**
     * change from pouchdb replicate
     */
    FileReplicator.prototype.pushChanges = function (change) {
        var items = [];
        if (change && change.docs && change.docs.length > 0) {
            for (var _i = 0, _a = change.docs; _i < _a.length; _i++) {
                var item = _a[_i];
                if (item[this._itemKey] && item[this._itemKey] === this._itemValue) {
                    items.push(item);
                }
            }
        }
        var files = this.prepareFiles(items);
        for (var _b = 0, files_1 = files; _b < files_1.length; _b++) {
            var file = files_1[_b];
            this._files.push(file);
        }
    };
    FileReplicator.prototype.downloadFiles = function (files, fileHandler, index) {
        var _this = this;
        if (index === void 0) { index = 0; }
        if (index >= files.length) {
            return;
        }
        this.emit('start', { progress: 0, index: index, length: files.length });
        fileHandler
            .download(files[index].source, files[index].target)
            .subscribe(function (progress) {
            _this.emit('progress', { progress: progress, index: index, length: files.length });
        }, function (error) {
            _this.emit('error', { progress: 0, index: index, length: files.length, error: error });
        }, function () {
            _this.emit('complete', { progress: 100, index: index, length: files.length });
            _this.downloadFiles(files, fileHandler, index + 1);
        });
    };
    FileReplicator.prototype.prepareFiles = function (items) {
        var output = [];
        for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
            var item = items_1[_i];
            if (item[this._itemSourceAttribute] && (!this._itemValidator || this._itemValidator(item))) {
                var file = { source: item[this._itemSourceAttribute], target: '' };
                if (item[this._itemTargetAttribute]) {
                    file.target = item[this._itemTargetAttribute];
                }
                else {
                    file.target = Util.getNameHash(file.source);
                }
                output.push(file);
            }
        }
        return output;
    };
    FileReplicator.prototype.start = function () {
        var _this = this;
        this.on('complete', function (event) {
            if ((event.index + 1) >= event.length) {
                _this.replicationFinalized(event.index);
            }
        });
        this.on('error', function (event) {
            _this.replicationFinalized(event.index);
        });
        this.downloadFiles(this._files, this._fileHandler);
    };
    FileReplicator.prototype.replicationFinalized = function (lastIndex) {
        var _this = this;
        if (lastIndex + 1 >= this._files.length) {
            this._files = [];
            this.emit('final');
        }
        else if (this._retryTimeout > 0) {
            this._files.splice(0, lastIndex);
            setTimeout(function () {
                _this.downloadFiles(_this._files, _this._fileHandler);
            }, this._retryTimeout);
        }
    };
    return FileReplicator;
}(events.EventEmitter));

var CONFIG_ITEM_KEY = "itemKey";
var CONFIG_ITEM_VALUE = "itemValue";
var CONFIG_ITEM_SOURCE_ATTRIBUTE = "itemSourceAttribute";
var CONFIG_ITEM_TARGET_ATTRIBUTE = "itemTargetAttribute";

var CONFIG_RETRY_TIMEOUT = "retryTimeout";

var Config = (function () {
    function Config() {
        this.config = {};
    }
    Config.prototype.hasConfig = function (key) {
        if (this.config[key]) {
            return true;
        }
        return false;
    };
    Config.prototype.getConfig = function (key) {
        return this.config[key];
    };
    Config.prototype.setConfig = function (key, value) {
        this.config[key] = value;
    };
    return Config;
}());

var ENV_ELECTRON = "electron";
var ENV_CORDOVA = "cordova";
var ENV_UNKNOWN = "unknown";
var ServiceLocator = (function () {
    function ServiceLocator() {
    }
    ServiceLocator.addFileHandler = function (environment, fileHandler) {
        ServiceLocator.fileHandlers[environment] = fileHandler;
    };
    ServiceLocator.getConfig = function () {
        if (!ServiceLocator.config) {
            ServiceLocator.config = new Config();
        }
        return ServiceLocator.config;
    };
    ServiceLocator.getEnvironment = function () {
        if (typeof window['require'] === 'function' && window['require']('electron')) {
            return ENV_ELECTRON;
        }
        if (typeof window['FileTransfer'] === 'function') {
            return ENV_CORDOVA;
        }
        return ENV_UNKNOWN;
    };
    ServiceLocator.getFileHandler = function () {
        var environment = ServiceLocator.getEnvironment();
        if (ServiceLocator.fileHandlers[environment]) {
            return ServiceLocator.fileHandlers[environment];
        }
        if (environment === ENV_ELECTRON) {
            return new ElectronFileHandler(window['require']('electron').ipcRenderer);
        }
        if (environment === ENV_CORDOVA) {
            return new CordovaDownloader();
        }
        return null;
    };
    ServiceLocator.getFileReplicator = function () {
        if (!ServiceLocator.fileReplicator) {
            ServiceLocator.fileReplicator = new FileReplicator();
            ServiceLocator.fileReplicator.fileHandler = ServiceLocator.getFileHandler();
            if (ServiceLocator.getConfig().hasConfig(CONFIG_RETRY_TIMEOUT)) {
                ServiceLocator.fileReplicator.retryTimeout = ServiceLocator.getConfig().getConfig(CONFIG_RETRY_TIMEOUT);
            }
            if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_KEY)) {
                ServiceLocator.fileReplicator.itemKey = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_KEY);
            }
            if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_VALUE)) {
                ServiceLocator.fileReplicator.itemValue = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_VALUE);
            }
            if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE)) {
                ServiceLocator.fileReplicator.itemSourceAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_SOURCE_ATTRIBUTE);
            }
            if (ServiceLocator.getConfig().hasConfig(CONFIG_ITEM_TARGET_ATTRIBUTE)) {
                ServiceLocator.fileReplicator.itemTargetAttribute = ServiceLocator.getConfig().getConfig(CONFIG_ITEM_TARGET_ATTRIBUTE);
            }
        }
        return ServiceLocator.fileReplicator;
    };
    ServiceLocator.fileHandlers = {};
    return ServiceLocator;
}());

function loadBsyncPlugin(PouchDB) {
    var pouchReplicate = PouchDB.replicate;
    PouchDB.plugin(function (PouchDB) {
        PouchDB.replicate = function () {
            var eventEmitter = new events.EventEmitter();
            var emitter = pouchReplicate.apply(this, arguments);
            var replicator = ServiceLocator.getFileReplicator();
            var db = arguments[1];
            replicator.once('final', function (event) {
                eventEmitter.emit('complete');
                eventEmitter.removeAllListeners();
            });
            replicator.on('error', function (event) {
                eventEmitter.emit('file-replicator-error', event);
            });
            replicator.on('complete', function (event) {
                eventEmitter.emit('file-replicator-complete', event);
            });
            replicator.on('progress', function (event) {
                eventEmitter.emit('file-replicator-progress', event);
            });
            emitter.once('change', function (info) {
                eventEmitter.emit('change', info);
            });
            emitter.once('complete', function (info) {
                db.query('index_type/type', {
                    include_docs: true,
                    key: replicator.itemValue
                }).then(function (res) {
                    var docs = { docs: [] };
                    for (var _i = 0, _a = res.rows; _i < _a.length; _i++) {
                        var r = _a[_i];
                        docs.docs.push(r.doc);
                    }
                    replicator.pushChanges(docs);
                    replicator.start();
                }).catch(function (error) {
                    eventEmitter.emit('error', error);
                });
            });
            emitter.once('error', function (error) {
                eventEmitter.emit('error', error);
            });
            return eventEmitter;
        };
    });
}

if (typeof window !== 'undefined' && window['PouchDB']) {
    loadBsyncPlugin(window['PouchDB']);
}

exports.loadBsyncPlugin = loadBsyncPlugin;
exports.ENV_ELECTRON = ENV_ELECTRON;
exports.ENV_CORDOVA = ENV_CORDOVA;
exports.ENV_UNKNOWN = ENV_UNKNOWN;
exports.ServiceLocator = ServiceLocator;
//# sourceMappingURL=browser-build.js.map