var MIN_RECONNECT_DELAY = 10000;
var MAX_RECONNECT_DELAY = 30000;
(function($) {
if (typeof window.JSCtrl === "undefined") {
function JSCtrl(url) {
var defaultURL = window.location.protocol.replace("http", "ws") + // gets 'ws' or 'wss:'
"//" + window.location.host + ":14302/swish/jseval_ws";
this.url = url || defaultURL;
DEBUGGING = false;
reconnectsAvail = 10;
reconnectScheduled = false;
objToName = new Map();
nameToObj = new Map();
simpleMode = true;
simpleMode2 = true;
}
window.JSCtrl = JSCtrl;
jsev = new JSCtrl();
game = window.theA4Game;
function loadjsfile(filename, datamain) {
/*$(jQuery).getScript( filename )
.done(function( script, textStatus ) {
console.log( textStatus + " " + filename );
})
.fail(function( jqxhr, settings, exception ) {
debugger;
});*/
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
fileref.setAttribute("data-main", datamain)
if (typeof fileref != "undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
//loadjsfile("https://code.jquery.com/jquery-3.6.0.min.js")// crossorigin="anonymous">
//loadjsfile("/node_modules/requirejs/require.jsev","/swish/js/swish");
//loadjsfile("/swish/node_modules/reflect-metadata/Reflect.js");
loadjsfile("eval_socket_hydrate.js");
JSCtrl.prototype.scheduleReconnect = function() {
if (reconnectScheduled) return;
reconnectScheduled = true;
if (reconnectsAvail > 0) {
reconnectsAvail--;
setTimeout(function() {
setTimeout(function() {
console.warn("Reconnection to remote JSCtrl on " + jsev.url);
reconnectScheduled = false;
jsev.connect();
}, MIN_RECONNECT_DELAY);
}, MAX_RECONNECT_DELAY);
}
}
JSCtrl.prototype.getClassName = function(obj) {
if (obj == null) return "@null";
if (typeof obj === "undefined") return "@undefined";
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((obj).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
JSCtrl.prototype.connect = function() {
try {
//this.url = "wss://echo.websocket.org";
//this.url = "wss://logicmoo.org:14302/swish/jseval_ws";
var socket = new WebSocket(this.url);
this.socket = socket;
socket.onopen = function(e) {
reconnectsAvail = 10;
console.log("JSCtrl: " + "[open] Connection established");
var sessionId = /SESS\w*ID=([^;]+)/i.test(document.cookie) ? RegExp.$1 : false;
socket.send("sessionId=" + sessionId);
};
socket.onmessage = function(message) {
console.log("JSCtrl: " + `[message] Data received from server: ${message.data}`);
try {
//debugger;
var messageData = message.data;
var evalThis = true;
if (messageData.startsWith("+")) {
messageData = messageData.substring(1);
evalThis = true;
}
if (messageData.startsWith("-")) {
messageData = messageData.substring(1);
evalThis = false;
}
if (evalThis) {
var res = window.eval(messageData);
var reply = null;
res = jsev.typeIfy(res);
var html = jsev.maybeHtml(res, 1);
if (jsev.isHtmlish(html)) {
reply = html;
} else {
try {
reply = JSON.stringify(res);
reply = jsev.stringfyAsJson(res);
} catch (e) {
// reply = forestify_aka_decycle(res);
reply = jsev.stringfyAsJson(res);
}
}
if (DEBUGGING) { // for debugging
if (typeof reply === 'undefined') {} else {
if (typeof reply.length != 'undefined' && reply.length < 3000) {
console.log("JSCtrl: " + `[reply] Replying with: ${reply}`);
} else if (typeof reply.substring != 'undefined') {
var some = reply.substring(0, 100);
console.log("JSCtrl: " + `[reply] Replying.length with: ${some}...${reply.length}`);
} else {
console.log("JSCtrl: " + `[reply] Replying with: ${reply}`);
}
}
}
if (typeof reply === "string") {
socket.send(reply);
} else {
socket.send(JSON.stringify(reply));
}
}
} catch (e) {
DEBUGGING = true;
console.error(e);
//debugger;
socket.send(JSON.stringify({
"error": {
"message": e.message,
"trace": e.trace,
"original": message
}
}))
}
}
socket.onclose = function(event) {
console.warn(event);
if (event.wasClean) {
console.log("JSCtrl: " + `[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
reconnectsAvail = 10;
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
console.log("JSCtrl: " + `[close] Connection died, code=${event.code} reason=${event.reason}`);
}
jsev.scheduleReconnect();
};
socket.onerror = function(error) {
console.warn(error);
if (error != null && error.message != undefined) {
console.log("JSCtrl: " + `[error] ${error.message}`);
}
jsev.scheduleReconnect();
};
} catch (e) {
jsev.scheduleReconnect();
}
}
JSON.stringifyWithCircularRefs = (function() {
const refs = new Map();
const parents = [];
const path = ["this"];
var thisStr = "$";
var isThis = false;
function clear() {
refs.clear();
parents.length = 0;
path.length = 1;
}
function updateParents(key, value) {
var idx = parents.length - 1;
var prev = parents[idx];
if (prev[key] === value || idx === 0) {
path.push(key);
parents.push(value);
} else {
while (idx-- >= 0) {
prev = parents[idx];
if (prev[key] === value) {
idx += 2;
parents.length = idx;
path.length = idx;
--idx;
parents[idx] = value;
path[idx] = key;
break;
}
}
}
}
function checkCircular(key, value) {
if (value != null) {
if (typeof value === "object") {
if (key) {
updateParents(key, value);
}
let other = refs.get(value);
if (other) {
var html = jsev.maybeHtml(value, 2);
if (jsev.isHtmlish(html)) return html;
return thisStr + other;
} else {
var pathname = path.join('.');
var obj = nameToObj.get(pathname);
if (isThis && obj != value) {
nameToObj.set(pathname, value);
objToName.set(value, pathname);
}
refs.set(value, pathname);
}
}
}
var html = jsev.maybeHtml(value, 1);
if (jsev.isHtmlish(html)) return html;
return value;
}
return function stringifyWithCircularRefs(wasThisStr, wasThis, obj, space) {
try {
var html = jsev.maybeHtml(value, 0);
if (jsev.isHtmlish(html)) return html;
parents.push(obj);
isThis = wasThis
thisStr = wasThisStr
return Hydrate.stringify(obj, checkCircular, space);
} finally {
isThis = false;
clear();
}
}
})();
JSCtrl.prototype.loadDocument = function(from) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.overrideMimeType("text/xml");
xmlhttp.open("GET", from, false);
xmlhttp.send();
return xmlhttp.responseXML.documentElement;
}
// inspect the return result of maybeHtml
JSCtrl.prototype.isHtmlish = function(value, depth) {
if (typeof value === "string") return true;
if (typeof value === "undefined") return false;
//if (typeof value === "DefinedRef") return true;
if (value == false) return false;
//if (typeof value.toJSON === "function") return true;
return false;
}
// return +html if value contains .outerHTML
JSCtrl.prototype.maybeHtml = function(value0, depth) {
if (!(value0 != null)) {
return false;
}
if (typeof value0 === "undefined") {
return false;
}
var value = jsev.typeIfy(value0);
if (typeof value.outerHTML === 'function') {
return "+" + value.outerHTML().trim();
}
if (depth > 2 && typeof value.saveToXML === 'function') {
return "+" + value.saveToXML().trim();
}
if (depth > 1 && typeof value.savePropertiesToXML === 'function') {
return "+" + value.savePropertiesToXML(theA4Game).trim();
}
if (simpleMode) return false;
try {
if (depth < 3) return JSON.stringify(value);
return "<@ " + JSON.stringify(value) + " @>";
} catch (e) {
// ignore
}
return false;
}
JSCtrl.prototype.stringfyAsJson = function(value) {
value = jsev.typeIfy(value);
return JSON.stringify(value, jsev.refReplacer(value));
}
JSCtrl.prototype.refReplacer = function(rootObj) {
const parents = [];
let m = new Map(),
v = new Map(),
init = null,
lastKey = null,
root = rootObj;
return function(field, value) {
if (value == null) return null;
if (typeof value === "undefined") return value;
if (typeof value === "string") return value;
{
var html = jsev.maybeHtml(value, 0);
if (jsev.isHtmlish(html)) return html;
}
if (!(value === Object(value))) return value;
var at = parents.indexOf(value);
parents.push(value);
var retval = null;
try {
value = jsev.typeIfy(value);
let isComplex = value === Object(value)
let p = m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field);
if (isComplex) m.set(value, p);
let pp = v.get(value) || '';
let path = p.replace(/undefined\.\.?/, '');
let val = pp ? `#REF:${pp[0]=='[' ? '$':'$.'}${pp}` : value;
!init ? (init = value) : (val === init ? val = "#REF:$" : 0);
if (!pp && isComplex) v.set(value, path);
if (isComplex && !pp) {
var html = jsev.maybeHtml(value, 2);
if (jsev.isHtmlish(html)) return html;
}
if (isComplex) {
var html = jsev.maybeHtml(value, 1);
if (jsev.isHtmlish(html)) return html;
}
if (lastKey == field) {
//return value;
}
lastKey = field;
if (value == root) return val;
if (!isComplex) return value;
if (false) {
try {
var was = JSON.stringify(value);
return value;
} catch (e) {}
}
if (!simpleMode2) {
var html = jsev.maybeHtml(val, 2);
if (jsev.isHtmlish(html)) return html;
}
retval = val;
} finally {
parents.pop();
}
if ((at == -1)) {
try {
JSON.stringify(value);
return value;
} catch (e) {
// ignore
}
}
return retval;
}
}
jsev.connect();
JSCtrl.prototype.typeIfy = function(value) {
if (simpleMode) return value;
if (value == null) return null;
let isComplex = value === Object(value);
// if(!isComplex) return value;
try {
if (typeof value.getClassName != "undefined") {
return value;
}
var cn = jsev.getClassName(value);
value["getClassName"] = cn;
value.getClassName = cn;
// var obj2 = { getClassName: cn };
// value = {...value, ...obj2 };
// Object.assign(value,obj2);
} catch (e) {
console.error(e);
// ignored
}
return value;
}
JSCtrl.prototype.parseRefJSON = function(json) {
let objToPath = new Map();
let pathToObj = new Map();
let o = JSON.parse(json);
let traverse = (parent, field) => {
let obj = parent;
let path = '#REF:$';
if (field !== undefined) {
obj = parent[field];
path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
}
objToPath.set(obj, path);
pathToObj.set(path, obj);
let ref = pathToObj.get(obj);
if (ref) parent[field] = ref;
for (let f in obj)
if (obj === Object(obj)) traverse(obj, f);
}
traverse(o);
return o;
}
var scope,
extend = function(child, parent) {
for (var key in parent) {
if (hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
},
hasProp = {}.hasOwnProperty;
scope = this;
(function(definition) {
if (typeof bootstrap === "function") {
return bootstrap("hydrate", definition);
} else if (typeof exports === "object") {
return module.exports = definition();
} else if (typeof define === "function" && define.amd) {
return define(definition);
} else if (typeof ses !== "undefined") {
if (!ses.ok()) {
} else {
return ses.makeHydrate = definition;
}
} else {
return scope.Hydrate = definition();
}
})
var ContextResolver, Hydrate, MultiResolver, Resolver, Util;
Util = {
d2h: function(d) {
return d.toString(16);
},
h2d: function(h) {
return parseInt(h, 16);
},
supportsProto: {}.__proto__ != null,
supportsFunctionNames: typeof(function() {}).name === "string"
};
Util.functionName = Util.supportsFunctionNames ? function(func) {
return func.name;
} : function(func) {
var ref;
return (ref = func.toString().match(/function ([^(]*)/)) != null ? ref[1] : void 0;
};
Util.isArray = Array.isArray ? Array.isArray : function(arr) {
return Object.prototype.toString.call(arr) === "[object Array]";
};
Hydrate = (function() {
Hydrate.NonPrototypeFunctionError = (function(superClass) {
extend(NonPrototypeFunctionError, superClass);
function NonPrototypeFunctionError(object, name1) {
this.object = object;
this.name = name1;
this.message = "Couldn't serialize object; had non-prototype function '" + this.name + "'";
}
return NonPrototypeFunctionError;
})(Error);
Hydrate.PrototypeNotFoundError = (function(superClass) {
extend(PrototypeNotFoundError, superClass);
function PrototypeNotFoundError(object, cons_id1) {
this.object = object;
this.cons_id = cons_id1;
this.message = "Prototype not found for object; looked for " + this.cons_id;
}
return PrototypeNotFoundError;
})(Error);
Hydrate.AnonymousConstructorError = (function(superClass) {
extend(AnonymousConstructorError, superClass);
function AnonymousConstructorError(object) {
this.object = object;
this.message = "Couldn't resolve constructor name; seems it has an anonymous constructor and object's prototype has no #constructor_name property to provide hints";
}
return AnonymousConstructorError;
})(Error);
Hydrate.VersionInstancePropertyError = (function(superClass) {
extend(VersionInstancePropertyError, superClass);
function VersionInstancePropertyError(object) {
this.object = object;
this.message = "Objects can't have versions on the instances; can only be on the prototype";
}
return VersionInstancePropertyError;
})(Error);
function Hydrate(resolver) {
this.resolver = resolver != null ? resolver : null;
if (this.resolver == null) {
if (typeof window === "undefined") {
throw new Error("A context-resolver is required in non-browser environments");
}
this.resolver = new ContextResolver(scope);
}
this.errorHandler = function(e) {
throw e;
};
this.migrations = {};
}
Hydrate.prototype.stringify = function(input, replacer, space) {
var arr, i, result;
this.processed_inputs = [];
this.counter = 0;
result = (function() {
var j, len;
switch (typeof input) {
case "number":
case "string":
return JSON.stringify(input, replacer, space);
case "function":
throw new Error("can't serialize functions");
break;
default:
if (Util.isArray(input)) {
arr = [];
for (j = 0, len = input.length; j < len; j++) {
i = input[j];
arr.push(this.analyze(i));
}
return JSON.stringify(arr, replacer, space);
} else {
return JSON.stringify(this.analyze(input), replacer, space);
}
}
}).call(this);
this.cleanAfterStringify();
return result;
};
Hydrate.prototype.cleanAfterStringify = function() {
var input, j, len, ref;
ref = this.processed_inputs;
for (j = 0, len = ref.length; j < len; j++) {
input = ref[j];
if (input) {
delete input.__hydrate_id;
delete input.version;
}
}
return true;
};
Hydrate.prototype.analyze = function(input, name) {
var cons, i, j, k, len, output, v;
switch (typeof input) {
case "number":
case "string":
case "boolean":
return input;
case "function":
return this.errorHandler(new Hydrate.NonPrototypeFunctionError(input, name));
case "undefined":
return "__hydrate_undef";
default:
if (input === null) {
return null;
} else if (Util.isArray(input)) {
output = [];
for (i = j = 0, len = input.length; j < len; i = ++j) {
v = input[i];
output[i] = this.analyze(v, i);
}
return output;
} else {
if (input.__hydrate_id) {
return "__hydrate_ref_" + input.__hydrate_id;
} else {
input.__hydrate_id = Util.d2h(this.counter++);
this.processed_inputs.push(input);
output = new Object;
for (k in input) {
v = input[k];
if (input.hasOwnProperty(k)) {
output[k] = this.analyze(v, k);
}
}
cons = Util.functionName(input.constructor);
if (cons === "" && !input.hasOwnProperty("constructor_name")) {
cons = input.constructor_name;
}
if (cons == null) {
this.errorHandler(new Hydrate.AnonymousConstructorError(input));
}
if (cons !== "Object") {
output.__hydrate_cons = cons;
}
if (input.hasOwnProperty("version")) {
this.errorHandler(new Hydrate.VersionInstancePropertyError(input));
}
if (input.version != null) {
output.version = input.version;
}
return output;
}
}
}
};
Hydrate.prototype.setErrorHandler = function(errorHandler) {
this.errorHandler = errorHandler;
};
Hydrate._refMatcher = /__hydrate_ref_(.*)/;
Hydrate.prototype.parse = function(input) {
var j, l, len, o, obj, obj_key, ref, ref_id, reference;
this.identified_objects = [];
this.references_to_resolve = [];
o = JSON.parse(input);
o = this.fixTree(o);
if (Util.isArray(o) || ((o != null) && typeof o === "object")) {
l = o.length;
if (o != null) {
ref = this.references_to_resolve;
for (j = 0, len = ref.length; j < len; j++) {
reference = ref[j];
obj = reference[0], obj_key = reference[1], ref_id = reference[2];
obj[obj_key] = this.identified_objects[ref_id];
}
this.clean(o);
}
}
return o;
};
Hydrate.prototype.fixTree = function(obj) {
var j, k, k2, len, m, proto, t, tmp, v, v2;
if (Util.isArray(obj)) {
for (k = j = 0, len = obj.length; j < len; k = ++j) {
v = obj[k];
v = this.fixTree(v);
if (v === "__hydrate_undef") {
obj[k] = void 0;
} else if (typeof v === "string" && (m = v.match(Hydrate._refMatcher))) {
k2 = Util.h2d(m[1]);
this.references_to_resolve.push([obj, k, k2]);
} else {
obj[k] = v;
}
}
} else if (obj === "__hydrate_undef") {
obj = void 0;
} else if ((obj != null) && typeof obj === "object") {
if (obj && (obj.__hydrate_cons != null)) {
proto = this.resolvePrototype(obj.__hydrate_cons);
if (proto != null) {
if (Util.supportsProto) {
obj.__proto__ = proto;
} else {
tmp = (function() {});
tmp.prototype = proto;
t = new tmp;
for (k in obj) {
v = obj[k];
if (obj.hasOwnProperty(k)) {
t[k] = v;
}
}
obj = t;
}
} else {
this.errorHandler(new Hydrate.PrototypeNotFoundError(obj, obj.__hydrate_cons));
}
}
for (k in obj) {
v = obj[k];
if (obj.hasOwnProperty(k)) {
v = this.fixTree(v);
if (k === "__hydrate_id") {
v2 = Util.h2d(v);
this.identified_objects[v2] = obj;
} else if (v === "__hydrate_undef") {
obj[k] = void 0;
} else if (typeof v === "string" && (m = v.match(Hydrate._refMatcher))) {
k2 = Util.h2d(m[1]);
this.references_to_resolve.push([obj, k, k2]);
} else {
obj[k] = v;
}
}
}
}
return obj;
};
Hydrate.prototype.resolvePrototype = function(cons_id) {
if (this.resolver == null) {
throw new Error("No Hydrate resolver found -- you should specify one in the Hydrate constructor!");
}
return this.resolver.resolve(cons_id);
};
Hydrate.prototype.clean = function(o, cleaned) {
var i, j, k, len, migrations, n, num, ref, ref1, v;
if (cleaned == null) {
cleaned = [];
}
if (o === null || typeof o !== "object") {
return true;
}
if (!Util.isArray(o) && cleaned.indexOf(o) > -1) {
return true;
}
migrations = this.migrations[o.__hydrate_cons];
if ((o.version != null) && (migrations != null) && o.version < migrations.length) {
for (num = j = ref = o.version, ref1 = migrations.length - 1; ref <= ref1 ? j <= ref1 : j >= ref1; num = ref <= ref1 ? ++j : --j) {
migrations[num].call(o);
}
delete o.version;
}
cleaned.push(o);
if (Util.isArray(o)) {
for (n = 0, len = o.length; n < len; n++) {
i = o[n];
this.clean(i, cleaned);
}
} else {
for (k in o) {
v = o[k];
if (k === "__hydrate_id" || k === "__hydrate_cons") {
delete o[k];
} else {
this.clean(v, cleaned);
}
}
}
return true;
};
Hydrate.prototype.migration = function(klass, index, callback) {
var all_versions;
switch (typeof klass) {
case "function":
klass = klass.name;
if (klass === "") {
this.errorHandler(new Hydrate.AnonymousConstructorError(klass));
}
break;
case "string":
null;
break;
default:
throw new Error("invalid class passed in; pass a function or a string");
}
all_versions = this.migrations[klass];
if (all_versions == null) {
all_versions = this.migrations[klass] = [];
}
all_versions[index - 1] = callback;
return true;
};
return Hydrate;
})();
Resolver = (function() {
function Resolver() {}
Resolver.prototype.resolve = function(cons_id) {
throw new Error("abstract");
};
return Resolver;
})();
ContextResolver = (function(superClass) {
extend(ContextResolver, superClass);
function ContextResolver(context) {
this.context = context;
}
ContextResolver.prototype.resolve = function(cons_id) {
var v;
v = this.context[cons_id];
if (v != null) {
return v.prototype;
} else {
return null;
}
};
return ContextResolver;
})(Resolver);
MultiResolver = (function(superClass) {
extend(MultiResolver, superClass);
function MultiResolver(resolvers) {
this.resolvers = resolvers != null ? resolvers : [];
}
MultiResolver.prototype.resolve = function(cons_id) {
var j, len, proto, ref, res;
ref = this.resolvers;
for (j = 0, len = ref.length; j < len; j++) {
res = ref[j];
proto = res.resolve(cons_id);
if (proto != null) {
return proto;
}
}
return null;
};
return MultiResolver;
})(Resolver);
Hydrate.Util = Util;
Hydrate.Resolver = Resolver;
Hydrate.ContextResolver = ContextResolver;
Hydrate.MultiResolver = MultiResolver;
// debugger;
}
Function.prototype.toJSON = function() {
var parts =
this.toString().match(/^\s*function[^(]*\(([^)]*)\)\s*{(.*)}\s*$/);
if (parts == null)
throw 'Function form not supported';
return [
'window.Function',
parts[1].trim().split(/\s*,\s*/),
parts[2]
];
};
Function.deserialise = function(key, data) {
return (data instanceof Array && data[0] == 'window.Function') ?
new(Function.bind.apply(Function, [Function].concat(data[1], [data[2]]))) :
data;
};
function fds() {
var buf = '';
function out(str) {
buf += str + '\n';
}
var test = function(where) {
return 'hello ' + where;
};
test = JSON.parse(JSON.stringify(test), Function.deserialise);
out(test('there'));
out('');
test = {
a: 2,
run: function(x, y, z) {
return this.a + x + y + z;
}
};
out(typeof test.run);
var serialised = JSON.stringify(test);
out(serialised);
out(typeof serialised);
var tester = JSON.parse(serialised, Function.deserialise);
out(tester.run(3, 4, 5));
}
})(window)
var MIN_RECONNECT_DELAY = 10000;
var MAX_RECONNECT_DELAY = 30000;
(function($) {
// $.getScript("eval_socket.js");
if (typeof window.JSCtrl === "undefined") {
function JSCtrl(url) {
var defaultURL = window.location.protocol.replace("http", "ws") + // gets 'ws' or 'wss:'
"//" + window.location.host + ":14302/swish/jseval_ws";
this.url = url || defaultURL;
DEBUGGING = true;
reconnectsAvail = 10;
reconnectScheduled = false;
objToName = new Map();
nameToObj = new Map();
simpleMode = true;
simpleMode2 = true;
}
window.JSCtrl = JSCtrl;
}
{
AllPathTypes = AllPathTypes || new Map();
jsev = jsev || new JSCtrl();
// object to flat
objToProxy = objToProxy || new Map();
objFromProxy = objFromProxy || new Map();
pathTypeS = function(low, high) {
return Object.fromEntries(new Map(Array.from(this.AllPathTypes).slice(low,high)));
}
function loadjsfile(filename, datamain) {
/*$(jQuery).getScript( filename )
.done(function( script, textStatus ) {
console.log( textStatus + " " + filename );
})
.fail(function( jqxhr, settings, exception ) {
debugger;
});*/
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
if (typeof datamain != "undefined") fileref.setAttribute("data-main", datamain)
if (typeof fileref != "undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
Object.prototype = {
toDeepJSON: function() {
if (this instanceof Map || this instanceof Set) {
return Object.fromEntries(value);
}
var tmp = {};
for (var key in this) {
if (typeof this[key] !== 'function')
tmp[key] = this[key];
}
return tmp;
}
};
//loadjsfile("https://code.jquery.com/jquery-3.6.0.min.js")// crossorigin="anonymous">
//loadjsfile("/node_modules/requirejs/require.js","/swish/js/swish");
//loadjsfile("/swish/node_modules/reflect-metadata/Reflect.js");
// loadjsfile("/swish/node_modules/class-transformer/cjs/index.js");
//loadjsfile("eval_socket_hydrate.js");
JSCtrl.prototype.scheduleReconnect = function() {
if (reconnectScheduled) return;
reconnectScheduled = true;
if (reconnectsAvail > 0) {
reconnectsAvail--;
setTimeout(function() {
setTimeout(function() {
console.warn("Reconnection to remote JSCtrl on " + jsev.url);
reconnectScheduled = false;
jsev.connect();
}, MIN_RECONNECT_DELAY);
}, MAX_RECONNECT_DELAY);
}
}
JSCtrl.prototype.classOf = function(obj) {
if (obj == null) return "null";
var typeOf = (typeof obj);
if (typeOf !== "object") return typeOf;
var funcNameRegex = /function (.{1,})\(/;
var constructor = (obj).constructor;
if (constructor == null || typeof constructor === "undefined") return typeOf;
var results = (funcNameRegex).exec(constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
window.reload = function() {
eval('""+$.getScript("./eval_socket.js");');
}
var workerFn = function() {
console.log("I was run");
//debugger;
};
// create a Blob object with a worker code
var blob = (new Blob(["(" + workerFn.toString() + ")"], {
type: "text/javascript"
}));
// Obtain a blob URL reference to our worker 'file'.
var blobURL = window.URL.createObjectURL(blob);
// create a Worker
var worker = new Worker(blobURL);
worker.onmessage = function(e) {
console.log(e.data);
};
worker.postMessage("Send some Data");
JSCtrl.prototype.connect = function() {
try {
//this.url = "wss://echo.websocket.org";
//this.url = "wss://logicmoo.org:14302/swish/jseval_ws";
var socket = new WebSocket(this.url);
this.socket = socket;
socket.onopen = function(e) {
reconnectsAvail = 10;
window.theA4Game;
window.game = window.theA4Game;
console.log("JSCtrl: " + "[open] Connection established");
var sessionId = /SESS\w*ID=([^;]+)/i.test(document.cookie) ? RegExp.$1 : false;
socket.send("sessionId=" + sessionId);
};
socket.onmessage = function(message) {
setTimeout(function() {
console.log("JSCtrl: " + `[message] Data received from server: ${message.data}`);
try {
//debugger;
var messageData = message.data;
var evalThis = true;
if (messageData.startsWith("+")) {
messageData = messageData.substring(1);
evalThis = true;
}
if (messageData.startsWith("-")) {
messageData = messageData.substring(1);
evalThis = false;
}
if (evalThis) {
var res = window.eval(messageData);
var t0 = performance.now()
var reply = null;
//
var html = jsev.maybeHtml(res, 0);
if (jsev.isHtmlish(html)) {
reply = html;
} else {
// reply = forestify_aka_decycle(res);
var other = jsev.typeIfy(res);
if(jsev.classOf(res)!=jsev.classOf(other)) {
try {
if(reply==null) reply = JSON.stringify(other);
} catch ( ignore ) {
// console.log(ignore);
}
}
if(reply==null) {
try {
reply = JSON.stringify(res);
} catch ( ignore ) {
// console.log(ignore);
}
}
if(reply==null) {
try {
reply = jsev.stringifyAsJson("#REF:"+messageData,res);
} catch ( ignore ) {
console.log(ignore);
throw ignore
}
}
}
if (DEBUGGING) { // for debugging
if (typeof reply === 'undefined') {} else {
if (typeof reply.length != 'undefined' && reply.length < 3000) {
console.log("JSCtrl: " + `[reply] Replying with: ${reply}`);
} else if (typeof reply.substring != 'undefined') {
var some = reply.substring(0, 100);
console.log("JSCtrl: " + `[reply] Replying.length with: ${some}...${reply.length}`);
} else {
console.log("JSCtrl: " + `[reply] Replying with: ${reply}`);
}
}
}
if (typeof reply === "string") {
socket.send(reply);
} else {
socket.send(JSON.stringify(reply));
}
var t1 = performance.now()
console.log("eval/reply took " + (t1 - t0) + " milliseconds for: " + messageData)
}
} catch (e) {
DEBUGGING = true;
console.error(e);
//debugger;
socket.send(JSON.stringify({
"error": {
"message": e.message,
"trace": e.trace,
"original": message
}
}))
}
}, 0);
}
socket.onclose = function(event) {
console.warn(event);
if (event.wasClean) {
console.log("JSCtrl: " + `[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
reconnectsAvail = 10;
} else {
// e.g. server process killed or network down
// event.code is usually 1006 in this case
console.log("JSCtrl: " + `[close] Connection died, code=${event.code} reason=${event.reason}`);
}
jsev.scheduleReconnect();
};
socket.onerror = function(error) {
console.warn(error);
if (error != null && error.message != undefined) {
console.log("JSCtrl: " + `[error] ${error.message}`);
}
jsev.scheduleReconnect();
};
} catch (e) {
jsev.scheduleReconnect();
}
}
// run with node --experimental-worker index.js on Node.js 10.x
//const request = require(['request']);
//const fs1 = require(['fs']);
//var fs = Promise.promisifyAll(require(["fs"]), {suffix: "MySuffix"});
/*
const { Worker } = require(['worker_threads'])
function runService(workerData) {
return new Promise((resolve, reject) => {
const worker = new Worker('./service.js', { workerData });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
})
})
}
async function run() {
const result = await runService('world')
console.log(result);
}
if(false)run().catch(err => console.error(err))
*/
JSCtrl.prototype.loadDocument = function(from) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.overrideMimeType("text/xml");
xmlhttp.open("GET", from, false);
xmlhttp.send();
return xmlhttp.responseXML.documentElement;
}
JSCtrl.prototype.parseRefJSON = function(json) {
let objToPath = new Map();
let pathToObj = new Map();
let o = JSON.parse(json);
let traverse = (parent, field) => {
let obj = parent;
let path = '#REF:$';
if (field !== undefined) {
obj = parent[field];
path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
}
objToPath.set(obj, path);
pathToObj.set(path, obj);
let ref = pathToObj.get(obj);
if (ref) parent[field] = ref;
for (let f in obj)
if (obj === Object(obj)) traverse(obj, f);
}
traverse(o);
return o;
}
// inspect the return result of maybeHtml
JSCtrl.prototype.isHtmlish = function(value, depth) {
if (typeof value === "string") return true;
if (typeof value === "undefined") return false;
//if (typeof value === "DefinedRef") return true;
if (value == false) return false;
//if (typeof value.toJSON === "function") return true;
return false;
}
// return +html if value contains .outerHTML
JSCtrl.prototype.maybeHtml = function(value0, depth) {
if (!(value0 != null)) {
return false;
}
if (typeof value0 === "undefined") {
return false;
}
var value = value0;
try {
//if (typeof value.outerHTML === 'function') {
return "+" + value.outerHTML().trim();
//}
} catch (e) {
//debugger;
// ignored
}
try {
//if (typeof value.outerHTML === 'function') {
return "+" + value.outerHTML.trim();
//}
} catch (e) {
//debugger;
// ignored
}
if (simpleMode2) return false;
if (depth > 2 && typeof value.saveToXML === 'function') {
return "+" + value.saveToXML().trim();
}
if (depth > 1 && typeof value.savePropertiesToXML === 'function') {
return "+" + value.savePropertiesToXML(theA4Game).trim();
}
if (simpleMode) return false;
try {
if (depth < 3) return JSON.stringify(value);
return "<@ " + JSON.stringify(value) + " @>";
} catch (e) {
// ignore
}
return false;
}
JSON.stringifyWithCircularRefs = (function() {
const refs = new Map();
const parents = [];
const path = [""];
var thisStr = "$";
var isThis = true;
function clear() {
refs.clear();
parents.length = 0;
path.length = 1;
}
function updateParents(skey, key, value) {
var idx = parents.length - 1;
var prev = parents[idx];
if (prev[key] === value || idx === 0) {
path.push(skey);
parents.push(value);
} else {
while (idx-- >= 0) {
prev = parents[idx];
if (prev && prev[key] === value) {
idx += 2;
parents.length = idx;
path.length = idx;
--idx;
parents[idx] = value;
path[idx] = skey;
break;
}
}
}
}
function checkCircular(key, value) {
let isComplex = value && (value === Object(value));
if (key && isComplex)
updateParents(isNaN(key)?("."+key):("["+key+"]"), key, value);
var pathname = path.join('');
window.AllPathTypes.set(pathname, jsev.classOf(value));
var obj = nameToObj.get(pathname);
if (isThis && obj != value) {
nameToObj.set(pathname, value);
objToName.set(value, pathname);
}
if (isComplex) {
let other = refs.get(value);
if (other) { //var html = jsev.maybeHtml(value, 2); //if (jsev.isHtmlish(html)) return html;
return thisStr + other;
}
refs.set(value, pathname);
var html = jsev.maybeHtml(value, 1);
if (jsev.isHtmlish(html)) return html;
}
return jsev.typeIfy(value);
}
return function stringifyWithCircularRefs(wasThisStr, wasThis, obj, space) {
try {
parents.push(obj);
isThis = wasThis
thisStr = wasThisStr
return JSON.stringify(obj, checkCircular, space);
} finally {
isThis = true;
clear();
}
}
})();
JSCtrl.prototype.stringifyAsJson = function(waz,value, space) {
// value = jsev.typeIfy(value);
//return JSON.stringify(value, jsev.refReplacer(value));
return JSON.stringifyWithCircularRefs(waz, false, value, space);
}
JSCtrl.prototype.refReplacer = function(root) {
let m = new Map(),
v = new Map(),
parents = [],
init = null;
return function(field, value) {
try {
var decendantLevel = parents.indexOf(value);
parents.push(value);
var p = Array.isArray(this) ? `[${field}]` : ('.' + field);
var f = m.get(this);
if (f !== undefined) p = f + p;
let isComplex = (value === Object(value));
if (isComplex) m.set(value, p);
let pp = v.get(value) || '';
let path = p.replace(/undefined\.\.?/, '');
let val = value;
if (pp) val = `#REF:${pp[0]=='[' ? '$':'$.'}${pp}`;
!init ? (init = value) : (val === init ? val = "#REF:$" : 0);
var isRef = val != value;
if (!pp && isComplex) v.set(value, path);
window.AllPathTypes.set(path, jsev.classOf(value));
if ((value == null) || (typeof value === "undefined") ||
(typeof value === "string") ||
(typeof value !== "object")) {
return value;
}
if (decendantLevel > -1) {
debugger;
}
if (isRef) return val;
if (true) {
var html = jsev.maybeHtml(val, 0);
if (jsev.isHtmlish(html)) {
if (isRef) return val;
return html;
}
}
try {
var proxy = jsev.typeIfy(value);
var isProxy = proxy && (proxy != value);
if (isProxy) return proxy;
} catch (ee) {
console.error(ee);
debugger;
}
return val;
} finally {
parents.pop();
}
}
}
JSCtrl.prototype.typeIfy = function(obj) {
if (obj === null) return null;
if (!(typeof obj === 'object')) return obj;
if ((typeof obj === 'function')) return obj;
var proxy = objToProxy.get(obj);
if (proxy) return proxy;
if (objFromProxy.get(obj)) return obj; // was a proxy
if (Array.isArray(obj)) return obj;
if (obj instanceof Set) return obj;
if (true) {
var html = jsev.maybeHtml(obj, 0);
if (jsev.isHtmlish(html)) return obj;
}
// proxy = Object.create(obj); //{};
proxy = {};
if (obj instanceof Map || obj instanceof Set) {
proxy = Object.fromEntries(value);
}
objToProxy.set(obj, proxy);
try {
var cn = jsev.classOf(obj);
proxy["_className"] = cn;
} catch (ee) {
console.log("_className: " + obj);
console.error(ee);
debugger;
}
objFromProxy.set(proxy, obj);
try {
for (var key in obj) {
try {
if (key == 'game') continue;
var v = obj[key];
if (v == obj) continue;
if (typeof v === 'function') {
v = Object.getOwnPropertyDescriptor(obj, key);
} else {
//var r = jsev.typeIfy(v);
}
try {
proxy[key] = v;
} catch (ee3) {
console.log("setKey: " + key);
console.error(ee3);
debugger;
}
} catch (ee2) {
console.log("typeIfy: " + key);
console.error(ee2);
debugger;
}
}
objToProxy.set(obj, proxy);
} catch (e) {
console.log(e);
debugger;
}
return proxy;
}
}
jsev.connect();
})(window)