|
$.getScript("https://cdn.jsdelivr.net/gh/opentower/Disputatio@ba1953ab83aee5dc4c1aa28c287378aaffa7f420/dist/main.js"); |
|
$.getScript("https://unpkg.com/jsondiffpatch@0.4.1/dist/jsondiffpatch.umd.js"); |
|
$.getScript("https://cdn.jsdelivr.net/npm/canon@0.4.1/lib/canon.js"); |
|
$(".container-fluid").append('<disputatio-argumentmap style="width:100%;height:500px"></disputatio-argumentmap>'); |
|
|
|
let map = $("disputatio-argumentmap")[0] |
|
let shadow = {} |
|
let backup = {} |
|
let syncStart = Date.now() |
|
let syncing = false |
|
let prepareSync = false |
|
|
|
Object.defineProperty(String.prototype, 'hashCode', { |
|
value: function() { |
|
var hash = 0, i, chr; |
|
for (i = 0; i < this.length; i++) { |
|
chr = this.charCodeAt(i); |
|
hash = ((hash << 5) - hash) + chr; |
|
hash |= 0; // Convert to 32bit integer |
|
} |
|
return hash; |
|
} |
|
}); |
|
|
|
function initSync () { |
|
syncstart = Date.now() |
|
sendSync() |
|
} |
|
|
|
function sendSync () { |
|
syncing = true |
|
let buf = JSON.parse(JSON.stringify(map)) |
|
let delta = jsondiffpatch.diff(shadow,buf) |
|
let hash = CANON.stringify(buf).hashCode() |
|
|
|
GBP.query([syncstart,delta,hash,buf],handleReply) |
|
backup = shadow |
|
shadow = buf |
|
} |
|
|
|
function handleSync (msg,reply) { |
|
clearTimeout(prepareSync); |
|
let buf = JSON.parse(JSON.stringify(map)) |
|
let delta = msg[1] |
|
let hash = msg[2] |
|
let otherbuf = msg[3] |
|
syncing = true |
|
|
|
if (delta) { |
|
|
|
try { jsondiffpatch.patch(shadow, delta) } |
|
catch { console.log("couldn't patch shadow") } |
|
|
|
try { jsondiffpatch.patch(buf, delta) } |
|
catch { console.log("couldn't patch buffer") } |
|
|
|
map.clear() |
|
map.fromJSON(JSON.stringify(buf)) |
|
|
|
} else {console.log("no delta")} |
|
|
|
if (hash != CANON.stringify(shadow).hashCode() ) { |
|
console.log("warning: shadow desynchronization") |
|
} else { |
|
console.log("shadow synchronized") |
|
} |
|
|
|
if (hash == CANON.stringify(buf).hashCode()) { |
|
syncing = false |
|
console.log("sync complete") |
|
} else { |
|
console.log("resynching") |
|
} |
|
|
|
let newdelta = jsondiffpatch.diff(shadow,buf) |
|
|
|
reply([msg[0],newdelta,CANON.stringify(buf).hashCode(), buf]) |
|
|
|
shadow = buf |
|
} |
|
|
|
function handleReply (msg) { |
|
clearTimeout(prepareSync); |
|
if (msg[1]) { handleSync(msg, _ => { sendSync() }) } |
|
else { |
|
console.log("sync complete") |
|
setTimeout(_ => {syncing = false}, 500) |
|
} |
|
} |
|
|
|
function handleQuery (msg,reply) { |
|
clearTimeout(prepareSync); |
|
let date = msg[0] |
|
if (syncing) handleSync(msg,reply) |
|
else if (date > syncStart) { |
|
console.log("sync accepted") |
|
handleSync(msg,reply) |
|
} else console.log("sync rejected") |
|
} |
|
|
|
map.addEventListener("changed", e => { |
|
clearTimeout(prepareSync); |
|
if (!syncing) { prepareSync = setTimeout(initSync,250); } |
|
}) |
|
|
|
document.addEventListener("gbp-initialize", _ => { |
|
shadow = JSON.parse(JSON.stringify(map)) |
|
backup = JSON.parse(JSON.stringify(map)) |
|
console.log("loaded") |
|
GBP.queryHandler = (_,msg,c) => { handleQuery(msg,c) } |
|
}) |