mirror of
https://github.com/mjl-/mox.git
synced 2024-12-28 17:33:47 +03:00
136 lines
3.1 KiB
Go
136 lines
3.1 KiB
Go
package sherpa
|
|
|
|
var sherpaJS = `
|
|
'use strict';
|
|
|
|
(function(undefined) {
|
|
|
|
var sherpa = {};
|
|
|
|
// prepare basic support for promises.
|
|
// we return functions with a "then" method only. our "then" isn't chainable. and you don't get other promise-related methods.
|
|
// but this "then" is enough so your browser's promise library (or a polyfill) can turn it into a real promise.
|
|
function thenable(fn) {
|
|
var settled = false;
|
|
var fulfilled = false;
|
|
var result = null;
|
|
|
|
var goods = [];
|
|
var bads = [];
|
|
|
|
// promise lib will call the returned function, make it the same as our .then function
|
|
var nfn = function(goodfn, badfn) {
|
|
if(settled) {
|
|
if(fulfilled && goodfn) {
|
|
goodfn(result);
|
|
}
|
|
if(!fulfilled && badfn) {
|
|
badfn(result);
|
|
}
|
|
} else {
|
|
if(goodfn) {
|
|
goods.push(goodfn);
|
|
}
|
|
if(badfn) {
|
|
bads.push(badfn);
|
|
}
|
|
}
|
|
};
|
|
nfn.then = nfn;
|
|
|
|
function done() {
|
|
while(fulfilled && goods.length > 0) {
|
|
goods.shift()(result);
|
|
}
|
|
while(!fulfilled && bads.length > 0) {
|
|
bads.shift()(result);
|
|
}
|
|
}
|
|
|
|
function makeSettle(xfulfilled) {
|
|
return function(arg) {
|
|
if(settled) {
|
|
return;
|
|
}
|
|
settled = true;
|
|
fulfilled = xfulfilled;
|
|
result = arg;
|
|
done();
|
|
};
|
|
}
|
|
var resolve = makeSettle(true);
|
|
var reject = makeSettle(false);
|
|
try {
|
|
fn(resolve, reject);
|
|
} catch(e) {
|
|
reject(e);
|
|
}
|
|
return nfn;
|
|
}
|
|
|
|
function postJSON(url, param, success, error) {
|
|
var req = new window.XMLHttpRequest();
|
|
req.open('POST', url, true);
|
|
req.onload = function onload() {
|
|
if(req.status >= 200 && req.status < 400) {
|
|
success(JSON.parse(req.responseText));
|
|
} else {
|
|
if(req.status === 404) {
|
|
error({code: 'sherpaBadFunction', message: 'function does not exist'});
|
|
} else {
|
|
error({code: 'sherpaHttpError', message: 'error calling function, HTTP status: '+req.status});
|
|
}
|
|
}
|
|
};
|
|
req.onerror = function onerror() {
|
|
error({code: 'sherpaClientError', message: 'connection failed'});
|
|
};
|
|
req.setRequestHeader('Content-Type', 'application/json');
|
|
req.send(JSON.stringify(param));
|
|
}
|
|
|
|
function makeFunction(api, name) {
|
|
return function() {
|
|
var params = Array.prototype.slice.call(arguments, 0);
|
|
return api._wrapThenable(thenable(function(resolve, reject) {
|
|
postJSON(api._sherpa.baseurl+name, {params: params}, function(response) {
|
|
if(response && response.error) {
|
|
reject(response.error);
|
|
} else if(response && response.hasOwnProperty('result')) {
|
|
resolve(response.result);
|
|
} else {
|
|
reject({code: 'sherpaBadResponse', message: "invalid sherpa response object, missing 'result'"});
|
|
}
|
|
}, reject);
|
|
}));
|
|
};
|
|
}
|
|
|
|
sherpa.init = function init(_sherpa) {
|
|
var api = {};
|
|
|
|
function _wrapThenable(thenable) {
|
|
return thenable;
|
|
}
|
|
|
|
function _call(name) {
|
|
return makeFunction(api, name).apply(Array.prototype.slice.call(arguments, 1));
|
|
}
|
|
|
|
api._sherpa = _sherpa;
|
|
api._wrapThenable = _wrapThenable;
|
|
api._call = _call;
|
|
for(var i = 0; i < _sherpa.functions.length; i++) {
|
|
var fn = _sherpa.functions[i];
|
|
api[fn] = makeFunction(api, fn);
|
|
}
|
|
|
|
return api;
|
|
};
|
|
|
|
|
|
var _sherpa = {{.sherpaJSON}};
|
|
window[_sherpa.id] = sherpa.init(_sherpa);
|
|
|
|
})();
|
|
`
|