Commit 3e152964 authored by Tristan Cavelier's avatar Tristan Cavelier

promy replaced by RSVP library

parent 78fe0cd7
......@@ -14,12 +14,6 @@ module.exports = function (grunt) {
errorsOnly: true
}
},
promy: {
src: ['src/promy/**/*.js'],
options: {
errorsOnly: true
}
},
jio: {
src: ['src/jio/**/*.js'],
exclude: ['src/jio/intro.js', 'src/jio/outro.js'],
......@@ -84,10 +78,6 @@ module.exports = function (grunt) {
banner: '/*! <%= pkg.name %> <%= pkg.version %> ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
promy: {
src: 'src/promy/promy.js',
dest: 'promy.min.js'
},
jio: {
src: 'jio.js', // '<%= pkg.name %>.js'
dest: 'jio.min.js'
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, regexp: true */
/*global constants, dictUpdate, deepClone */
function restCommandRejecter(param, args) {
// reject(status, reason, message, {"custom": "value"});
// reject(status, reason, {..});
// reject(status, {..});
var a = args[0], b = args[1], c = args[2], d = args[3], weak, strong;
weak = {"result": "error"};
strong = {};
weak.status = constants.http_status.unknown;
weak.statusText = constants.http_status_text.unknown;
weak.message = 'Command failed';
weak.reason = 'fail';
weak.method = param.method;
if (param.kwargs._id) {
weak.id = param.kwargs._id;
}
if (/Attachment$/.test(param.method)) {
weak.attachment = param.kwargs._attachment;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.status = constants.http_status[a];
strong.statusText = constants.http_status_text[a];
if (strong.status === undefined ||
strong.statusText === undefined) {
return restCommandRejecter(param, [
// can create infernal loop if 'internal_storage_error' is not defined
// in the constants
'internal_storage_error',
'invalid response',
'Unknown status "' + a + '"'
]);
}
a = b;
b = c;
c = d;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.reason = a;
a = b;
b = c;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.message = a;
a = b;
}
if (typeof a === 'object' && !Array.isArray(a)) {
dictUpdate(weak, a);
}
dictUpdate(weak, strong);
strong = undefined;
if (weak.error === undefined) {
weak.error = weak.statusText.toLowerCase().replace(/ /g, '_').
replace(/[^_a-z]/g, '');
}
if (typeof weak.message !== 'string') {
weak.message = "";
}
if (typeof weak.reason !== 'string') {
weak.reason = "unknown";
}
return param.solver.reject(deepClone(weak));
}
/*jslint indent: 2, maxlen: 80, nomen: true, sloppy: true, regexp: true */
/*global Deferred, inherits, constants, dictUpdate, deepClone, Blob,
methodType */
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global constants, methodType, dictUpdate, Blob, deepClone,
restCommandRejecter */
function IODeferred(method, info) {
IODeferred.super_.call(this);
this._info = info || {};
this._method = method;
// this._options = options;
}
inherits(IODeferred, Deferred);
IODeferred.prototype.resolve = function (a, b) {
function restCommandResolver(param, args) {
// resolve('ok', {"custom": "value"});
// resolve(200, {...});
// resolve({...});
var weak = {"result": "success"}, strong = {};
if (this._method === 'post') {
var a = args[0], b = args[1], weak = {"result": "success"}, strong = {};
if (param.method === 'post') {
weak.status = constants.http_status.created;
weak.statusText = constants.http_status_text.created;
} else if (methodType(this._method) === "writer" ||
this._method === "check") {
} else if (methodType(param.method) === "writer" ||
param.method === "check") {
weak.status = constants.http_status.no_content;
weak.statusText = constants.http_status_text.no_content;
} else {
weak.status = constants.http_status.ok;
weak.statusText = constants.http_status_text.ok;
}
if (this._info._id) {
weak.id = this._info._id;
if (param.kwargs._id) {
weak.id = param.kwargs._id;
}
if (/Attachment$/.test(this._method)) {
weak.attachment = this._info._attachment;
if (/Attachment$/.test(param.method)) {
weak.attachment = param.kwargs._attachment;
}
weak.method = this._method;
weak.method = param.method;
if (typeof a === 'string' || (typeof a === 'number' && isFinite(a))) {
strong.status = constants.http_status[a];
strong.statusText = constants.http_status_text[a];
if (strong.status === undefined ||
strong.statusText === undefined) {
return this.reject(
return restCommandRejecter(param, [
'internal_storage_error',
'invalid response',
'Unknown status "' + a + '"'
);
]);
}
a = b;
}
......@@ -52,14 +44,14 @@ IODeferred.prototype.resolve = function (a, b) {
}
dictUpdate(weak, strong);
strong = undefined; // free memory
if (this._method === 'post' && (typeof weak.id !== 'string' || !weak.id)) {
return this.reject(
if (param.method === 'post' && (typeof weak.id !== 'string' || !weak.id)) {
return restCommandRejecter(param, [
'internal_storage_error',
'invalid response',
'New document id have to be specified'
);
]);
}
if (this._method === 'getAttachment') {
if (param.method === 'getAttachment') {
if (typeof weak.data === 'string') {
weak.data = new Blob([weak.data], {
"type": weak.content_type || weak.mimetype || ""
......@@ -68,111 +60,21 @@ IODeferred.prototype.resolve = function (a, b) {
delete weak.mimetype;
}
if (!(weak.data instanceof Blob)) {
return this.reject(
return restCommandRejecter(param, [
'internal_storage_error',
'invalid response',
'getAttachment method needs a Blob as returned "data".'
);
]);
}
} else if (methodType(this._method) === 'reader' &&
this._method !== 'check' &&
} else if (methodType(param.method) === 'reader' &&
param.method !== 'check' &&
(typeof weak.data !== 'object' ||
Object.getPrototypeOf(weak.data) !== Object.prototype)) {
return this.reject(
return restCommandRejecter(param, [
'internal_storage_error',
'invalid response',
this._method + ' method needs a dict as returned "data".'
);
}
//return super_resolve(deepClone(weak));
return IODeferred.super_.prototype.resolve.call(this, deepClone(weak));
};
IODeferred.prototype.reject = function (a, b, c, d) {
// reject(status, reason, message, {"custom": "value"});
// reject(status, reason, {..});
// reject(status, {..});
var weak = {"result": "error"}, strong = {};
weak.status = constants.http_status.unknown;
weak.statusText = constants.http_status_text.unknown;
weak.message = 'Command failed';
weak.reason = 'fail';
weak.method = this._method;
if (this._info._id) {
weak.id = this._info._id;
}
if (/Attachment$/.test(this._method)) {
weak.attachment = this._info._attachment;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.status = constants.http_status[a];
strong.statusText = constants.http_status_text[a];
if (strong.status === undefined ||
strong.statusText === undefined) {
return this.reject(
// can create infernal loop if 'internal_storage_error' is not defined
// in the constants
'internal_storage_error',
'invalid response',
'Unknown status "' + a + '"'
);
}
a = b;
b = c;
c = d;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.reason = a;
a = b;
b = c;
}
if (typeof a !== 'object' || Array.isArray(a)) {
strong.message = a;
a = b;
}
if (typeof a === 'object' && !Array.isArray(a)) {
dictUpdate(weak, a);
param.method + ' method needs a dict as returned "data".'
]);
}
dictUpdate(weak, strong);
strong = undefined;
if (weak.error === undefined) {
weak.error = weak.statusText.toLowerCase().replace(/ /g, '_').
replace(/[^_a-z]/g, '');
}
if (typeof weak.message !== 'string') {
weak.message = "";
}
if (typeof weak.reason !== 'string') {
weak.reason = "unknown";
}
//return super_reject(deepClone(weak));
return IODeferred.super_.prototype.reject.call(this, deepClone(weak));
};
IODeferred.createFromDeferred = function (method, info, options, deferred) {
var iodeferred = new IODeferred(method, info, options);
// iodeferred.promise().done(deferred.resolve.bind(deferred)).
// fail(deferred.reject.bind(deferred)).
// progress(deferred.notify.bind(deferred));
// // phantomjs doesn't like 'bind'...
iodeferred.promise.then(
deferred.resolve.bind(deferred),
deferred.reject.bind(deferred),
deferred.notify.bind(deferred)
);
return iodeferred;
};
IODeferred.createFromParam = function (param) {
return IODeferred.createFromDeferred(
param.method,
param.kwargs,
param.options,
param.deferred
);
};
return param.solver.resolve(deepClone(weak));
}
/*jslint indent: 2, maxlen: 80, nomen: true, sloppy: true */
/*global exports, Blob, FileReader, Deferred, hex_sha256, XMLHttpRequest,
/*global exports, Blob, FileReader, RSVP, hex_sha256, XMLHttpRequest,
constants */
/**
......@@ -310,32 +310,41 @@ function makeBinaryStringDigest(string) {
exports.util.makeBinaryStringDigest = makeBinaryStringDigest;
function readBlobAsBinaryString(blob) {
var deferred = new Deferred(), fr = new FileReader();
fr.addEventListener("load", deferred.resolve.bind(deferred));
fr.addEventListener("error", deferred.reject.bind(deferred));
fr.addEventListener("progress", deferred.notify.bind(deferred));
fr.readAsBinaryString(blob);
return deferred.promise;
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsBinaryString(blob);
}, function () {
fr.abort();
});
}
exports.util.readBlobAsBinaryString = readBlobAsBinaryString;
function readBlobAsArrayBuffer(blob) {
var deferred = new Deferred(), fr = new FileReader();
fr.addEventListener("load", deferred.resolve.bind(deferred));
fr.addEventListener("error", deferred.reject.bind(deferred));
fr.addEventListener("progress", deferred.notify.bind(deferred));
fr.readAsArrayBuffer(blob);
return deferred.promise;
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsArrayBuffer(blob);
}, function () {
fr.abort();
});
}
exports.util.readBlobAsArrayBuffer = readBlobAsArrayBuffer;
function readBlobAsText(blob) {
var deferred = new Deferred(), fr = new FileReader();
fr.addEventListener("load", deferred.resolve.bind(deferred));
fr.addEventListener("error", deferred.reject.bind(deferred));
fr.addEventListener("progress", deferred.notify.bind(deferred));
fr.readAsText(blob);
return deferred.promise;
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsText(blob);
}, function () {
fr.abort();
});
}
exports.util.readBlobAsText = readBlobAsText;
......@@ -355,29 +364,33 @@ exports.util.readBlobAsText = readBlobAsText;
* @return {Promise} The promise
*/
function ajax(param) {
var k, xhr = new XMLHttpRequest(), deferred = new Deferred();
xhr.open(param.type || "GET", param.url, true);
xhr.responseType = param.dataType || "";
if (typeof param.headers === 'object' && param.headers !== null) {
for (k in param.headers) {
if (param.headers.hasOwnProperty(k)) {
xhr.setRequestHeader(k, param.headers[k]);
var xhr = new XMLHttpRequest();
return new RSVP.Promise(function (resolve, reject, notify) {
var k;
xhr.open(param.type || "GET", param.url, true);
xhr.responseType = param.dataType || "";
if (typeof param.headers === 'object' && param.headers !== null) {
for (k in param.headers) {
if (param.headers.hasOwnProperty(k)) {
xhr.setRequestHeader(k, param.headers[k]);
}
}
}
}
xhr.addEventListener("load", function (e) {
if (e.target.status >= 400) {
return deferred.reject(e);
xhr.addEventListener("load", function (e) {
if (e.target.status >= 400) {
return reject(e);
}
resolve(e);
});
xhr.addEventListener("error", reject);
xhr.addEventListener("progress", notify);
if (typeof param.beforeSend === 'function') {
param.beforeSend(xhr);
}
deferred.resolve(e);
xhr.send(param.data);
}, function () {
xhr.abort();
});
xhr.addEventListener("error", deferred.reject.bind(deferred));
xhr.addEventListener("progress", deferred.notify.bind(deferred));
if (typeof param.beforeSend === 'function') {
param.beforeSend(xhr);
}
xhr.send(param.data);
return deferred.promise;
}
exports.util.ajax = ajax;
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, unparam: true */
/*global arrayInsert, indexOf, deepClone, defaults, IODeferred */
/*global arrayInsert, indexOf, deepClone, defaults, restCommandRejecter */
// creates
// - some defaults job rule actions
......@@ -8,11 +8,12 @@ function enableJobChecker(jio, shared, options) {
// dependencies
// - shared.jobs Object Array
// - param.promise Object
// creates
// - shared.job_rules Array
// uses 'job' events
// uses 'job' event
var i;
......@@ -20,24 +21,25 @@ function enableJobChecker(jio, shared, options) {
shared.job_rule_actions = {
wait: function (original_job, new_job) {
original_job.deferred.promise.always(function () {
original_job.promise.always(function () {
shared.emit('job', new_job);
});
new_job.state = 'waiting';
new_job.modified = new Date();
},
update: function (original_job, new_job) {
if (!new_job.deferred) {
if (!new_job.solver) {
// promise associated to the job
new_job.state = 'done';
shared.emit('jobDone', new_job);
} else {
if (!original_job.deferred) {
original_job.deferred = new_job.deferred;
if (!original_job.solver) {
original_job.solver = new_job.solver;
} else {
original_job.deferred.promise.
done(new_job.command.resolve).
fail(new_job.command.reject);
original_job.promise.then(
new_job.command.resolve,
new_job.command.reject
);
}
}
new_job.state = 'running';
......@@ -46,11 +48,11 @@ function enableJobChecker(jio, shared, options) {
deny: function (original_job, new_job) {
new_job.state = 'fail';
new_job.modified = new Date();
IODeferred.createFromParam(new_job).reject(
restCommandRejecter(new_job, [
'precondition_failed',
'command denied',
'Command rejected by the job checker.'
);
]);
}
};
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, unparam: true */
/*global setTimeout, Job, createStorage, deepClone, IODeferred, min */
/*global setTimeout, Job, createStorage, deepClone, min, restCommandResolver,
restCommandRejecter */
function enableJobExecuter(jio, shared) { // , options) {
......@@ -46,44 +47,30 @@ function enableJobExecuter(jio, shared) { // , options) {
});
shared.on('jobDone', function (param, args) {
var d;
if (param.state === 'running') {
param.state = 'done';
param.modified = new Date();
shared.emit('jobEnd', param);
if (param.deferred) {
d = IODeferred.createFromDeferred(
param.method,
param.kwargs,
param.options,
param.deferred
);
d.resolve.apply(d, args);
if (param.solver) {
restCommandResolver(param, args);
}
}
});
shared.on('jobFail', function (param, args) {
var d;
if (param.state === 'running') {
param.state = 'fail';
param.modified = new Date();
shared.emit('jobEnd', param);
if (param.deferred) {
d = IODeferred.createFromDeferred(
param.method,
param.kwargs,
param.options,
param.deferred
);
d.reject.apply(d, args);
if (param.solver) {
restCommandRejecter(param, args);
}
}
});
shared.on('jobNotify', function (param, args) {
if (param.state === 'running' && param.deferred) {
param.deferred.notify.apply(param.deferred, args);
if (param.state === 'running' && param.solver) {
param.solver.notify(args[0]);
}
});
}
......@@ -58,7 +58,7 @@ function enableJobMaker(jio, shared, options) {
shared.rest_method_names.forEach(function (method) {
shared.on(method, function (param) {
if (param.deferred) {
if (param.solver) {
// params are good
shared.emit('job', param);
}
......
/*jslint indent: 2, maxlen: 80, sloppy: true */
/*global arrayValuesToTypeDict, dictClear, Deferred, deepClone */
/*global arrayValuesToTypeDict, dictClear, RSVP, deepClone */
// adds methods to JIO
// - post
......@@ -18,7 +18,12 @@
// - method string
// - kwargs object
// - options object
// - command object
// - solver object
// - solver.resolve function
// - solver.reject function
// - solver.notify function
// - cancellers object
// - promise object
function enableRestAPI(jio, shared) { // (jio, shared, options)
......@@ -36,7 +41,7 @@ function enableRestAPI(jio, shared) { // (jio, shared, options)
];
function prepareParamAndEmit(method, storage_spec, args) {
var promise, callback, type_dict, param = {};
var callback, type_dict, param = {};
type_dict = arrayValuesToTypeDict(Array.prototype.slice.call(args));
type_dict.object = type_dict.object || [];
if (method !== 'allDocs') {
......@@ -49,31 +54,38 @@ function enableRestAPI(jio, shared) { // (jio, shared, options)
} else {
param.kwargs = {};
}
param.solver = {};
param.options = deepClone(type_dict.object.shift()) || {};
//param.deferred = new IODeferred(method, param.kwargs, param.options);
param.deferred = new Deferred();
promise = param.deferred.promise;
param.promise = new RSVP.Promise(function (resolve, reject, notify) {
param.solver.resolve = resolve;
param.solver.reject = reject;
param.solver.notify = notify;
}, function () {
var k;
for (k in param.cancellers) {
if (param.cancellers.hasOwnProperty(k)) {
param.cancellers[k]();
}
}
});
type_dict['function'] = type_dict['function'] || [];
if (type_dict['function'].length === 1) {
callback = type_dict['function'].shift();
promise.done(function (answer) {
callback = type_dict['function'][0];
param.promise.then(function (answer) {
callback(undefined, answer);
});
promise.fail(function (answer) {
}, function (answer) {
callback(answer, undefined);
});
} else if (type_dict['function'].length > 1) {
promise.done(type_dict['function'].shift());
promise.fail(type_dict['function'].shift());
if (type_dict['function'].length === 1) {
promise.always(type_dict['function'].shift());
}
param.promise.then(type_dict['function'][0],
type_dict['function'][1],
type_dict['function'][2]);
}
type_dict = dictClear(type_dict);
param.storage_spec = storage_spec;
param.method = method;
shared.emit(method, param);
return promise;
return param.promise;
}
shared.createRestApi = function (storage_spec, that) {
......
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true, unparam: true */
/*global Blob, IODeferred, Metadata */
/*global Blob, restCommandRejecter, Metadata */
function enableRestParamChecker(jio, shared) {
// dependencies
// - param.deferred
// - param.solver
// - param.kwargs
// checks the kwargs and convert value if necessary
......@@ -17,12 +17,12 @@ function enableRestParamChecker(jio, shared) {
function checkId(param) {
if (typeof param.kwargs._id !== 'string' || param.kwargs._id === '') {
IODeferred.createFromParam(param).reject(
restCommandRejecter(param, [
'bad_request',
'wrong document id',
'Document id must be a non empty string.'
);
delete param.deferred;
]);
delete param.solver;
return false;
}
return true;
......@@ -31,12 +31,12 @@ function enableRestParamChecker(jio, shared) {
function checkAttachmentId(param) {
if (typeof param.kwargs._attachment !== 'string' ||
param.kwargs._attachment === '') {
IODeferred.createFromParam(param).reject(
restCommandRejecter(param, [
'bad_request',
'wrong attachment id',
'Attachment id must be a non empty string.'
);
delete param.deferred;
]);
delete param.solver;
return false;
}
return true;
......@@ -84,15 +84,15 @@ function enableRestParamChecker(jio, shared) {
delete param.kwargs._mimetype;
delete param.kwargs._content_type;
} else {
IODeferred.createFromParam(param).reject(
restCommandRejecter(param, [
'bad_request',
'wrong attachment',
'Attachment information must be like {"_id": document id, ' +
'"_attachment": attachment name, "_data": string, ["_mimetype": ' +
'content type]} or {"_id": document id, "_attachment": ' +
'attachment name, "_blob": Blob}'
);
delete param.deferred;
]);
delete param.solver;
}
});
......
......@@ -4,11 +4,11 @@
return define(dependencies, module);
}
if (typeof exports === 'object') {
return module(exports, require('promy'), require('sha256'));
return module(exports, require('rsvp'), require('sha256'));
}
window.jIO = {};
module(window.jIO, promy, {hex_sha256: hex_sha256});
}(['exports', 'promy', 'sha256'], function (exports, promy, sha256) {
module(window.jIO, RSVP, {hex_sha256: hex_sha256});
}(['exports', 'rsvp', 'sha256'], function (exports, RSVP, sha256) {
"use strict";
var hex_sha256 = sha256.hex_sha256, Deferred = promy.Deferred;
var hex_sha256 = sha256.hex_sha256;
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment