urbit/base/lib/urb.js

294 lines
8.3 KiB
JavaScript
Raw Normal View History

2015-03-20 02:35:10 +03:00
window.urb.seqn_u = 1
2015-03-20 01:21:14 +03:00
window.urb.dely = 0
2015-03-20 02:35:10 +03:00
window.urb.puls = false
2015-03-20 01:21:14 +03:00
window.urb.cabs = {}
if(!window.urb.appl) window.urb.appl = null
window.urb.req = function(method,url,params,json,cb) {
var xhr = new XMLHttpRequest()
2015-03-20 02:35:10 +03:00
method = method.toUpperCase()
if(method == "PUT" || method == "DELETE")
xhr.open("POST", url+"?"+method)
else xhr.open(method, url)
2015-03-20 01:21:14 +03:00
if(json)
xhr.setRequestHeader("content-type", "text/json")
2015-03-26 23:37:25 +03:00
if(!window.urb.oryx) throw "No CSRF token" // XX fetch auth.json
2015-03-20 01:21:14 +03:00
_data = {oryx: window.urb.oryx}
if(params.xyro) { _data.xyro = params.xyro; }
if(params.ship) { _data.ship = params.ship; }
if(params.path) { _data.path = params.path; }
if(params.appl) { _data.appl = params.appl; }
if(params.mark) { _data.mark = params.mark; }
2015-04-07 02:36:07 +03:00
if(params.wire) { _data.wire = params.wire; }
2015-03-20 01:21:14 +03:00
if(cb) {
xhr.onload = function() {
try {
err = null
res = {
status:this.status,
data: JSON.parse(this.responseText)
}
if(res.data.reload)
res.reload = res.data.reload
} catch(e) {
if(urb.wall !== false) document.write(this.responseText) // XX
2015-03-20 01:21:14 +03:00
err = {
message:"Failed to parse JSON",
raw:this.responseText
}
res = null
}
cb(err,res)
}
xhr.onerror = function() {
cb({
status:this.status,
data:this.responseText
})
}
}
xhr.send(JSON.stringify(_data))
}
2015-05-15 21:27:44 +03:00
// window.urb.getJSON = function(url,cb){ window.urb.reqJSON("GET",url, null, cb)}
// window.urb.reqJSON = function(method, url, data, cb){
// var xhr = new XMLHttpRequest()
// xhr.open(method, url)
// xhr.onload = function(){
// urb.fetchTag.call(xhr)
// if(cb) cb(JSON.parse(xhr.responseText))
// }
// xhr.send(data === null ? null : JSON.stringify(data))
// }
2015-03-20 01:21:14 +03:00
window.urb.reqq = []
window.urb.qreq = function(method,url,params,json,cb) {
walk = function() {
qobj = {}
qobj.oargs = window.urb.reqq[0]
qobj.nargs = [].slice.apply(qobj.oargs,[0,4])
qobj.nargs.push(function(){
if(this.oargs[4])
this.oargs[4].apply(window.urb,arguments)
window.urb.reqq.shift()
if(window.urb.reqq.length > 0)
walk()
}.bind(qobj))
window.urb.req.apply(this,qobj.nargs)
}
l = window.urb.reqq.length
window.urb.reqq.push(arguments);
if(l == 0) { walk() }
}
window.urb.gsig = function(params) {
var path = params.path
if(!path) path = ""
2015-04-07 02:36:07 +03:00
if(path[0] !== "/") path = "/"+path
2015-03-20 02:35:10 +03:00
return "~"+params.ship+"/"+
2015-03-20 01:21:14 +03:00
params.appl+
path.replace(/[^\x00-\x7F]/g, "")
}
2015-03-20 02:35:10 +03:00
window.urb.poll = function(params) {
if(!params) throw new Error("You must supply params to urb.poll.")
2015-03-20 01:21:14 +03:00
2015-03-20 02:35:10 +03:00
var url, $this
2015-03-20 01:21:14 +03:00
seqn = this.seqn_u
2015-03-20 02:35:10 +03:00
if(params.seqn) seqn = params.seqn()
2015-03-20 01:21:14 +03:00
2015-03-20 02:35:10 +03:00
url = "/~/of/"+this.ixor+"?poll="+seqn
2015-03-20 01:21:14 +03:00
2015-03-20 02:35:10 +03:00
this.puls = true
2015-03-20 01:21:14 +03:00
$this = this
this.req("get",url,params,true,function(err,res) {
if(res){
if(res.data.beat)
2015-03-20 02:35:10 +03:00
return $this.poll(params)
switch(res.data.type){
2015-03-20 02:35:10 +03:00
case "news":
return document.location.reload() // XX check autoreload
case "rush":
2015-03-27 04:01:28 +03:00
case "mean":
2015-04-08 21:46:05 +03:00
var err2 = err
2015-04-07 23:36:33 +03:00
if(res.data.type == "mean")
2015-04-08 21:46:05 +03:00
err2 = res.data.data
var fn = $this.gsig(res.data.from)
2015-03-20 02:35:10 +03:00
if($this.cabs[fn])
2015-04-08 21:46:05 +03:00
$this.cabs[fn].call(this,err2,
{status: res.status, data: res.data.data.json}) // XX non-json
2015-03-20 02:35:10 +03:00
break;
default:
2015-03-27 04:01:28 +03:00
throw new Error("Lost event %"+res.data.type)
2015-03-20 01:21:14 +03:00
}
}
2015-03-20 02:35:10 +03:00
dely = params.dely ? params.dely : $this.dely
2015-03-20 01:21:14 +03:00
if(err)
dely = dely+Math.ceil(dely*.02)
else {
$this.dely = 0
if(params.incs)
params.incs()
2015-03-20 02:35:10 +03:00
else
2015-03-20 01:21:14 +03:00
$this.seqn_u++
}
setTimeout(function() {
2015-03-20 02:35:10 +03:00
$this.poll(params)
2015-03-20 01:21:14 +03:00
},dely)
})
}
2015-03-20 02:35:10 +03:00
// if (window.urb.auto) { // need dependencies
// var tries = 0
// var cnt = 0
// var param = {
// type:"pol"
// }
// window.urb.poll(param)
// }
2015-03-20 01:21:14 +03:00
// window.urb.heartbeat = function() {
// this.poll({
// type:"heb",
// ship:this.ship,
// dely:30000,
// seqn:function() {
// return window.urb.seqn_h
// },
// incs:function() {
// window.urb.seqn_h = window.urb.seqn_h+1
// }
// },function() {
// console.log('heartbeat.')
// })
// }
// window.urb.heartbeat()
// // / // / // //
// end old %eyre code //
// // / // / // //
2014-08-01 03:57:35 +04:00
window.urb.seqn_s = 0
2015-03-20 01:21:14 +03:00
// TODO urb.send(data, [params/params.appl]?, cb?)
window.urb.send = function(params,cb) {
2014-08-01 03:57:35 +04:00
if(!params)
throw new Error("You must supply params to urb.send.")
2015-03-20 01:21:14 +03:00
if(!params.appl && !this.appl){
throw new Error("You must specify an appl for urb.send.")
}
2014-08-01 03:57:35 +04:00
2015-03-20 01:21:14 +03:00
var url, $this
2014-08-01 03:57:35 +04:00
params.ship = params.ship ? params.ship : this.ship
2015-03-20 01:21:14 +03:00
params.appl = params.appl ? params.appl : this.appl
2014-10-24 01:09:39 +04:00
params.mark = params.mark ? params.mark : "json"
2015-03-20 01:21:14 +03:00
params.xyro = params.data ? params.data : {}
2015-04-07 02:43:46 +03:00
params.wire = params.wire ? params.wire : "/"
2014-08-01 03:57:35 +04:00
2015-03-20 01:21:14 +03:00
url = ["to",params.appl,params.mark]
url = "/~/"+url.join("/")
2014-08-01 03:57:35 +04:00
this.seqn_s++
$this = this
2015-03-20 01:21:14 +03:00
this.qreq('post',url,params,true,function(err,data) {
2014-08-01 03:57:35 +04:00
if(err) { $this.seqn_s--; }
if(cb) { cb.apply(this,arguments); }
})
}
2015-03-20 02:35:10 +03:00
window.urb.subscribe = function(params,cb) { // legacy interface
if(!params) throw new Error("You must supply params to urb.subscribe")
return window.urb.bind(params.path, params, cb, cb)
2015-03-20 02:35:10 +03:00
}
window.urb.bind = function(path, cb){ // or bind(path, params, cb, nicecb?)
var params, nicecb
if(arguments.length > 2)
{params = cb; cb = arguments[2], nicecb = arguments[3]}
else params = {}
params.path = path
2015-04-07 02:36:07 +03:00
if(params.path[0] !== "/") params.path = "/"+params.path
params.ship = params.ship ? params.ship : this.ship
params.appl = params.appl ? params.appl : this.appl
2015-03-27 01:32:32 +03:00
params.mark = params.mark ? params.mark : "json"
2015-04-07 02:36:07 +03:00
params.wire = params.wire ? params.wire : params.path
2015-04-07 02:36:07 +03:00
if(typeof path != "string")
throw new Error("You must specify a string path for urb.bind.")
2015-03-20 02:35:10 +03:00
if(!params.appl) throw new Error("You must specify an appl for urb.bind.")
if(!cb) throw new Error("You must supply a callback to urb.bind.")
2014-08-01 03:57:35 +04:00
var method, perm, url, $this
2015-03-27 01:32:32 +03:00
if(params.mark !== "json")
throw new Error("Non-json subscriptions unimplemented.") // XX
url = "/~/is/"+this.gsig(params)+"."+params.mark
2015-04-07 02:36:07 +03:00
params.path = params.wire
this.cabs[this.gsig(params)] = cb
2014-08-01 03:57:35 +04:00
$this = this
this.qreq("put",url,params,true,function(err,res) {
if(nicecb) { nicecb.apply(this,[err,{status: res.status, data: res.data}])}
2015-03-20 02:35:10 +03:00
// XX give raw data
//
if(!err && !$this.puls) $this.poll(params)
2014-08-01 03:57:35 +04:00
})
2014-07-17 06:10:13 +04:00
}
2014-07-29 03:17:59 +04:00
2014-08-01 03:57:35 +04:00
window.urb.unsubscribe = function(params,cb) {
2015-03-27 02:29:17 +03:00
if(!params) throw new Error("You must supply params to urb.unsubscribe.")
2014-08-01 03:57:35 +04:00
params.ship = params.ship ? params.ship : this.ship
2015-03-27 02:29:17 +03:00
params.appl = params.appl ? params.appl : this.appl
2015-04-07 02:43:46 +03:00
params.wire = params.wire ? params.wire : params.path
2014-08-01 03:57:35 +04:00
2015-03-27 02:29:17 +03:00
if(!params.path) throw new Error("You must specify a path for urb.unsubscribe.")
if(!params.appl) throw new Error("You must specify an appl for urb.unsubscribe.")
2015-04-11 01:45:17 +03:00
url = "/~/is/"+this.gsig(params)+".json"
2015-03-27 02:29:17 +03:00
method = "delete"
this.req("delete",url,params,true,function(err,res) {
2015-05-15 00:59:45 +03:00
if(cb) cb(err,res)
2014-08-01 03:57:35 +04:00
})
}
2014-12-10 02:51:18 +03:00
window.urb.util = {
isURL: function(s) {
r = new RegExp('^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$', 'i');
return s.length < 2083 && r.test(s);
},
2015-04-10 20:55:07 +03:00
numDot: function(n) {
_n = String(n)
fun = function(s){
if(s.length <= 3)
return s
return fun(s.slice(0,-3))+"."+s.slice(-3)
}
return fun((_n))
2015-04-10 20:55:07 +03:00
},
2014-12-10 02:51:18 +03:00
toDate: function (dat){
var mils = Math.floor((0x10000 * dat.getUTCMilliseconds()) / 1000).toString(16)
2015-01-09 22:57:15 +03:00
function pad(num, str){
return ((new Array(num + 1)).join('0') + str).substr(-num,num)
}
2014-12-10 02:51:18 +03:00
return '~' + dat.getUTCFullYear() +
'.' + (dat.getUTCMonth() + 1) +
'.' + dat.getUTCDate() +
2015-01-09 22:57:15 +03:00
'..' + pad(2, dat.getUTCHours()) +
'.' + pad(2, dat.getUTCMinutes()) +
'.' + pad(2, dat.getUTCSeconds()) +
'..' + pad(4, mils)
2014-12-10 02:51:18 +03:00
}
}