UNPKG

cc.fovea.cordova.purchase

Version:

Cordova Purchase plugin for iOS, Android, Windows (AppStore, Play, UWP)

185 lines (164 loc) 6.53 kB
(function(){ /// /// ## *store._queries* object /// The `queries` object handles the callbacks registered for any given couple /// of [query](#queries) and action. /// /// Internally, the magic is found within the [`triggerWhenProduct`](#triggerWhenProduct) /// method, which generates for a given product the list of all possible /// queries that describe the product. /// /// Queries are generated using the id, alias, type or validity of the product. /// store._queries = { /// ### *store._queries.uniqueQuery(string)* /// Transform a human readable query string /// into a unique string by filtering out reserved keywords: /// uniqueQuery: function(string) { if (!string) return ''; var query = ''; var tokens = string.split(' '); for (var i = 0; i < tokens.length; ++i) { var token = tokens[i]; if (token !== 'order' && /// - `order` token !== 'product') { /// - `product` if (query !== '') query += ' '; query += token; } /// } return query; }, /// ### *store._queries.callbacks* object /// Callbacks registered organized by query strings callbacks: { /// #### *store._queries.callbacks.byQuery* dictionary /// Dictionary of: /// /// - *key*: a string equals to `query + " " + action` /// - *value*: array of callbacks /// /// Each callback have the following attributes: /// /// - `cb`: callback *function* /// - `once`: *true* iff the callback should be called only once, then removed from the dictionary. /// byQuery: {}, /// #### *store._queries.callbacks.add(query, action, callback, once)* /// Simplify the query with `uniqueQuery()`, then add it to the dictionary. /// /// `action` is concatenated to the `query` string to create the key. add: function(query, action, cb, once) { var fullQuery = store._queries.uniqueQuery(query ? query + " " + action : action); if (this.byQuery[fullQuery]) this.byQuery[fullQuery].push({cb:cb, once:once}); else this.byQuery[fullQuery] = [{cb:cb, once:once}]; // store.log.debug("queries ++ '" + fullQuery + "'"); }, unregister: function(cb) { var keep = function(o) { return o.cb !== cb; }; for (var i in this.byQuery) this.byQuery[i] = this.byQuery[i].filter(keep); } }, /// ### *store._queries.triggerAction(action, args)* /// Trigger the callbacks registered when a given `action` (string) /// happens, unrelated to a product. /// /// `args` are passed as arguments to the registered callbacks. /// triggerAction: function(action, args) { var cbs = store._queries.callbacks.byQuery[action]; // store.log.debug("queries !! '" + action + "'"); if (cbs) { /// - Call the callbacks for (var j = 0; j < cbs.length; ++j) { try { cbs[j].cb.apply(store, args); } catch (err) { store.utils.logError(action, err); } } /// - Remove callbacks that needed to be called only once store._queries.callbacks.byQuery[action] = cbs.filter(isNotOnce); } /// }, /// ### *store._queries.triggerWhenProduct(product, action, args)* /// Trigger the callbacks registered when a given `action` (string) /// happens to a given [`product`](#product). /// /// `args` are passed as arguments to the registered callbacks. /// triggerWhenProduct: function(product, action, args) { /// The method generates all possible queries for the given `product` and `action`. var queries = []; /// /// - product.id + " " + action if (product && product.id) queries.push(product.id + " " + action); /// - product.alias + " " + action if (product && product.alias && product.alias !== product.id) queries.push(product.alias + " " + action); /// - product.type + " " + action if (product && product.type) queries.push(product.type + " " + action); /// - "subscription " + action (if type is a subscription) if (product && product.type && (product.type === store.FREE_SUBSCRIPTION || product.type === store.PAID_SUBSCRIPTION)) queries.push("subscription " + action); /// - "valid " + action (if product is valid) if (product && product.valid === true) queries.push("valid " + action); /// - "invalid " + action (if product is invalid) if (product && product.valid === false) queries.push("invalid " + action); /// - action queries.push(action); /// /// Then, for each query: /// var i; for (i = 0; i < queries.length; ++i) { var q = queries[i]; // store.log.debug("store.queries !! '" + q + "'"); var cbs = store._queries.callbacks.byQuery[q]; if (cbs) { /// - Call the callbacks for (var j = 0; j < cbs.length; ++j) { try { cbs[j].cb.apply(store, args); } catch (err) { // Generate a store error. store.utils.logError(q, err); // We will throw the exception, but later, // first let all callbacks do their job. deferThrow(err); } } /// - Remove callbacks that needed to be called only once store._queries.callbacks.byQuery[q] = cbs.filter(isNotOnce); } } /// /// **Note**: All events also trigger the `updated` event if (action !== "updated" && action !== 'error') this.triggerWhenProduct(product, "updated", [ product ]); } /// }; // isNotOnce return true iff a callback should be called more than once. function isNotOnce(cb) { return !cb.once; } function deferThrow(err) { setTimeout(function() { throw err; }, 1); } })();