<commit_before>// Copyright (c) 2013 M-Way Solutions GmbH
// http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt

/**
 * The Bikini.BikiniStore is used to connect a model collection to an
 * bikini server.
 *
 * This will give you an online and offline store with live data updates.
 *
 * @module Bikini.BikiniStore
 *
 * @type {*}
 * @extends Bikini.Store
 *
 * @example
 *
 * // The default configuration will save the complete model data as a json,
 * // and the offline change log to a local WebSql database, synchronize it
 * // trough REST calls with the server and receive live updates via a socket.io connection.
 *
 * var MyCollection = Bikini.Collection.extend({
 *      model: MyModel,
 *      url: 'http://myBikiniServer.com:8200/bikini/myCollection',
 *      store: new Bikini.BikiniStore( {
 *          useLocalStore:   YES, // (default) store the data for offline use
 *          useSocketNotify: YES, // (default) register at the server for live updates
 *          useOfflineChanges: YES // (default) allow changes to the offline data
 *      })
 * });
 *
 */
Bikini.BikiniStore = Bikini.Store.extend({

    _type: 'Bikini.BikiniStore',

    _selector: null,

    endpoints: {},

    options: null,

    localStore: Bikini.WebSqlStore,

    useLocalStore: YES,

    useSocketNotify: YES,

    useOfflineChanges: YES,

    isConnected: NO,

    typeMapping: {
        'binary': 'text',
        'date': 'string'
    },

    initialize: function( options ) {
        Bikini.Store.prototype.initialize.apply(this, arguments);
        this.options = this.options || {};
        this.options.useLocalStore = this.useLocalStore;
        this.options.useSocketNotify = this.useSocketNotify;
        this.options.useOfflineChanges = this.useOfflineChanges;
        this.options.socketPath = this.socketPath;
        this.options.localStore = this.localStore;
        this.options.typeMapping = this.typeMapping;
        if( this.options.useSocketNotify && typeof io !== 'object' ) {
            console.log('Socket.IO not present !!');
            this.options.useSocketNotify = NO;
        }
        _.extend(this.options, options || {});
    },

    initModel: function( model ) {
    },

    initCollection: function( collection ) {
        var url = collection.getUrlRoot();
        var entity = this.getEntity(collection.entity);
        if( url && entity ) {
            var name = entity.name;
            var hash = this._hashCode(url);
            var credentials = entity.credentials || collection.credentials;
            var user = credentials && credentials.username ? credentials.username : '';
            var channel = name + user + hash;
            collection.channel = channel;
            // get or create endpoint for this url
            var that = this;
            var endpoint = this.endpoints[hash];
            if( !endpoint ) {
                var href = this.getLocation(url);
                endpoint = {};
                endpoint.baseUrl = url;
                endpoint.readUrl = collection.getUrl();
                endpoint.host = href.protocol + '//' + href.host;
                endpoint.path = href.pathname;
                endpoint.entity = entity;
                endpoint.channel = channel;
                endpoint.credentials = credentials;
                endpoint.socketPath = this.options.socketPath;
                endpoint.localStore = this.createLocalStore(endpoint);
                endpoint.messages = this.createMsgCollection(endpoint);
                endpoint.socket = this.createSocket(endpoint);
                endpoint.info = this.fetchServerInfo(endpoint);
                that.endpoints[hash] = endpoint;
            }
            collection.endpoint = endpoint;
            collection.listenTo(this, endpoint.channel, this.onMessage, collection);
        }
    },

    getEndpoint: function( url ) {
        if( url ) {
            var hash = this._hashCode(url);
            return this.endpoints[hash];
        }
    },

    createLocalStore: function( endpoint, idAttribute ) {
        if( this.options.useLocalStore && endpoint ) {
            var entities = {};
            entities[endpoint.entity.name] = {
                name: endpoint.channel,
                idAttribute: idAttribute
            };
            return this.options.localStore.create({
                entities: entities
            });
        }
    },

    createMsgCollection: function( endpoint ) {
        if( this.options.useOfflineChanges && endpoint ) {
            var messages = Bikini.Collection.design({
                url: endpoint.url,
                entity: 'msg-' + endpoint.channel,
                store: this.options.localStore.create()
            });
            var that = this;
            messages.fetch({
                success: function() {
                    that.sendMessages(endpoint);
                }
            });
            return messages;
        }
    },

    createSocket: function( endpoint, name ) {
        if( this.options.useSocketNotify && endpoint && endpoint.socketPath) {
            var that = this;
            var url  = endpoint.host;
            var path = endpoint.path;
            //path = endpoint.socketPath || (path + (path.charAt(path.length - 1) === '/' ? '' : '/' ) + 'live');
            path = endpoint.socketPath;
            // remove leading /
            var resource = (path && path.indexOf('/') === 0) ? path.substr(1) : path;

            endpoint.socket = io.connect(url, { resource: resource });<commit_msg>added fix that the wrong port was added to Socket endpoint if you use local proxy<commit_after>// Copyright (c) 2013 M-Way Solutions GmbH
// http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt

/**
 * The Bikini.BikiniStore is used to connect a model collection to an
 * bikini server.
 *
 * This will give you an online and offline store with live data updates.
 *
 * @module Bikini.BikiniStore
 *
 * @type {*}
 * @extends Bikini.Store
 *
 * @example
 *
 * // The default configuration will save the complete model data as a json,
 * // and the offline change log to a local WebSql database, synchronize it
 * // trough REST calls with the server and receive live updates via a socket.io connection.
 *
 * var MyCollection = Bikini.Collection.extend({
 *      model: MyModel,
 *      url: 'http://myBikiniServer.com:8200/bikini/myCollection',
 *      store: new Bikini.BikiniStore( {
 *          useLocalStore:   YES, // (default) store the data for offline use
 *          useSocketNotify: YES, // (default) register at the server for live updates
 *          useOfflineChanges: YES // (default) allow changes to the offline data
 *      })
 * });
 *
 */
Bikini.BikiniStore = Bikini.Store.extend({

    _type: 'Bikini.BikiniStore',

    _selector: null,

    endpoints: {},

    options: null,

    localStore: Bikini.WebSqlStore,

    useLocalStore: YES,

    useSocketNotify: YES,

    useOfflineChanges: YES,

    isConnected: NO,

    typeMapping: {
        'binary': 'text',
        'date': 'string'
    },

    initialize: function( options ) {
        Bikini.Store.prototype.initialize.apply(this, arguments);
        this.options = this.options || {};
        this.options.useLocalStore = this.useLocalStore;
        this.options.useSocketNotify = this.useSocketNotify;
        this.options.useOfflineChanges = this.useOfflineChanges;
        this.options.socketPath = this.socketPath;
        this.options.localStore = this.localStore;
        this.options.typeMapping = this.typeMapping;
        if( this.options.useSocketNotify && typeof io !== 'object' ) {
            console.log('Socket.IO not present !!');
            this.options.useSocketNotify = NO;
        }
        _.extend(this.options, options || {});
    },

    initModel: function( model ) {
    },

    initCollection: function( collection ) {
        var url = collection.getUrlRoot();
        var entity = this.getEntity(collection.entity);
        if( url && entity ) {
            var name = entity.name;
            var hash = this._hashCode(url);
            var credentials = entity.credentials || collection.credentials;
            var user = credentials && credentials.username ? credentials.username : '';
            var channel = name + user + hash;
            collection.channel = channel;
            // get or create endpoint for this url
            var that = this;
            var endpoint = this.endpoints[hash];
            if( !endpoint ) {
                var href = this.getLocation(url);
                endpoint = {};
                endpoint.baseUrl = url;
                endpoint.readUrl = collection.getUrl();
                endpoint.host = href.protocol + '//' + href.host;
                endpoint.path = href.pathname;
                endpoint.entity = entity;
                endpoint.channel = channel;
                endpoint.credentials = credentials;
                endpoint.socketPath = this.options.socketPath;
                endpoint.localStore = this.createLocalStore(endpoint);
                endpoint.messages = this.createMsgCollection(endpoint);
                endpoint.socket = this.createSocket(endpoint);
                endpoint.info = this.fetchServerInfo(endpoint);
                that.endpoints[hash] = endpoint;
            }
            collection.endpoint = endpoint;
            collection.listenTo(this, endpoint.channel, this.onMessage, collection);
        }
    },

    getEndpoint: function( url ) {
        if( url ) {
            var hash = this._hashCode(url);
            return this.endpoints[hash];
        }
    },

    createLocalStore: function( endpoint, idAttribute ) {
        if( this.options.useLocalStore && endpoint ) {
            var entities = {};
            entities[endpoint.entity.name] = {
                name: endpoint.channel,
                idAttribute: idAttribute
            };
            return this.options.localStore.create({
                entities: entities
            });
        }
    },

    createMsgCollection: function( endpoint ) {
        if( this.options.useOfflineChanges && endpoint ) {
            var messages = Bikini.Collection.design({
                url: endpoint.url,
                entity: 'msg-' + endpoint.channel,
                store: this.options.localStore.create()
            });
            var that = this;
            messages.fetch({
                success: function() {
                    that.sendMessages(endpoint);
                }
            });
            return messages;
        }
    },

    createSocket: function( endpoint, name ) {
        if( this.options.useSocketNotify && endpoint && endpoint.socketPath) {
            var that = this;
            var url  = endpoint.host;
            var path = endpoint.path;
            var href = this.getLocation(url);
            if(href.port === '') {
                if(href.protocol === 'https:') {
                    url += ':443';
                } else if(href.protocol === 'http:') {
                    url += ':80';
                }
            }

            //path = endpoint.socketPath || (path + (path.charAt(path.length - 1) === '/' ? '' : '/' ) + 'live');
            path = endpoint.socketPath;
            // remove leading /
            var resource = (path && path.indexOf('/') === 0) ? path.substr(1) : path;

            endpoint.socket = io.connect(url, { resource: resource });
{'fraction_non_alphanumeric': 0.11285676878764074, 'fraction_numerical': 0.002356637863315004, 'mean_word_length': 1.8781713137402662, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3199400', 'n_tokens_mistral': 3094, 'n_tokens_neox': 2954, 'n_words': 730}