web3.js/lib/filter.js

137 lines
4.5 KiB
JavaScript

/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file filter.js
* @authors:
* Jeffrey Wilcke <[email protected]>
* Marek Kotewicz <[email protected]>
* Marian Oancea <[email protected]>
* Gav Wood <[email protected]>
* @date 2014
*/
/// Should be called to check if filter implementation is valid
/// @returns true if it is, otherwise false
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
typeof i.getLogs === 'function' &&
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
};
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
/// @param should be string or object
/// @returns options string or object
var getOptions = function (options) {
if (typeof options === 'string') {
return options;
}
options = options || {};
if (options.topics) {
console.warn('"topics" is deprecated, is "topic" instead');
}
// evaluate lazy properties
return {
to: options.to,
topic: options.topic,
earliest: options.earliest,
latest: options.latest,
max: options.max,
skip: options.skip,
address: options.address
};
};
/// Should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// @param options are filter options
/// @param implementation, an abstract polling implementation
/// @param formatter (optional), callback function which formats output before 'real' callback
var filter = function(options, implementation, formatter) {
if (!implementationIsValid(implementation)) {
console.error('filter implemenation is invalid');
return;
}
options = getOptions(options);
var callbacks = [];
var filterId = implementation.newFilter(options);
var onMessages = function (messages) {
messages.forEach(function (message) {
message = formatter ? formatter(message) : message;
callbacks.forEach(function (callback) {
callback(message);
});
});
};
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
var watch = function(callback) {
callbacks.push(callback);
};
var stopWatching = function() {
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
var get = function () {
return implementation.getLogs(filterId);
};
return {
watch: watch,
stopWatching: stopWatching,
get: get,
// DEPRECATED methods
changed: function(){
console.warn('watch().changed() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
arrived: function(){
console.warn('watch().arrived() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
happened: function(){
console.warn('watch().happened() is deprecated please use filter().watch() instead.');
return watch.apply(this, arguments);
},
uninstall: function(){
console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');
return stopWatching.apply(this, arguments);
},
messages: function(){
console.warn('watch().messages() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
},
logs: function(){
console.warn('watch().logs() is deprecated please use filter().get() instead.');
return get.apply(this, arguments);
}
};
};
module.exports = filter;