UNPKG

godprotocol

Version:

A distributed computing environment for Web 4.0 — integrating AI, decentralisation, and virtual computation.

331 lines (279 loc) 8.33 kB
import Arr from "../Datatypes/arr.js"; import Num from "../Datatypes/num.js"; import Str from "../Datatypes/str.js"; import Twa from "../Datatypes/twa.js"; import Voi from "../Datatypes/voi.js"; import Bool from "../Datatypes/bool.js"; import Instance from "../Datatypes/instance.js"; import Func from "../Datatypes/func.js"; import Cls from "../Datatypes/cls.js"; import Err from "../Datatypes/err.js"; import { ops } from "./ops.js"; import Fold from "godprotocol/Instances/fold.js"; import Res from "godprotocol/Instances/response.js"; import { hash } from "godprotocol/utils/hash.js"; class Vm_utils { constructor() { this.ops = ops; this.datatypes = ["string", "number", "void", "boolean", "array", "twain"]; } gen_location = (addr) => { return `${addr || this.account.physical_address}/${this.gen_uid(true)}`; }; error_instance = async (err_payload, alias) => { let { chain, manager } = this.account; let res = await this.instantiate( { type: "error", ...err_payload }, { chain } ); if (alias) { await (await manager.ds.folder(alias.location)).write(res); } }; variable = async (address, { chain, config, obj }) => { let result; let chn = await chain.chain(address); let fold = await chn.folder(); if (config && config._id && config.type === "reference") { result = { type: "address", value: address, _id: config._id, }; if (config.object) result.object = config.object; } else result = await fold.readone( config && config._id ? { _id: config._id } : null ); if (obj) result = await this.cloth(result); return result; }; gen_uid = (loc) => { return `_${Math.random().toString().replace(".", "")}${ loc ? "" : "_" }${Date.now()}`; }; spread_properties = async (object, cls, { lists, benches }) => { for (let m in cls.methods) { object.methods[m] = cls.methods[m]; } for (let p in cls.properties) { let prop = cls.properties[p]; let res = await this.nodelist(prop); lists.push(...res); benches[p] = lists.length - 1; } }; base_classes = async ( object, config, { inherited, lists, benches, chain } ) => { for (let b = 0; b < config.base_classes.length; b++) { let blc = config.base_classes[b]; if (inherited.includes(blc.location)) continue; let cls = await this.cloth(await this.variable(blc.location, { chain }), { just_content: true, }); await this.spread_properties(object, cls, { lists, benches }); if (cls.base_classes.length) await this.base_classes(object, cls, { inherited, chain }); } }; retrieve = async (object, o) => { let obj, addr; if (object.type === "instance") { let cls = await this.cloth({ type: "function", address: object.cls, // _id: object.cls_id }); addr = await cls.get_instance(object, true); if (o) { obj = await this.cloth(addr); } } else if (["twain", "array"].includes(object.type)) { obj = await this.cloth_content(object); await obj.retrieve(object.entries || object.items); addr = await obj.to_address(); } else if (object.type === "function") { console.log(object, "in here"); // process.exit() obj = object; addr = await object.to_address(); } else { obj = await this.cloth_content(object); addr = await obj.to_address(); } return o ? obj : addr; }; parse_dynamic = async (literal, options = {}) => { let { chain, config } = options; let aircode = this.account.aircode; let sequence = aircode.to_sequence( JSON.stringify(literal), chain.physical_address ); let res = await chain.add_config(sequence[0].body[0]); let address = await this.execute(res, { chain }); return address; }; folder = async (fold) => { return { type: "folder", repo: fold.config.repo, value: fold.address, _id: await this.hash(fold.address), }; }; base_val = async (type) => { let result; switch (type) { case "string": result = ""; break; case "number": result = "0"; break; case "array": result = []; break; case "twain": result = {}; break; case "boolean": result = false; } return await this.typecast(result, type, true); }; resolve_addr = (addr) => { if (!addr) return addr; if (addr.startsWith("@")) { addr = `${this.account.physical_address}/${addr.slice(2)}`; } return addr; }; typecast = async (obj, type) => { return obj; }; _split_datapath = (datapath) => { datapath = datapath.split("/"); return [datapath.slice(0, -1).join("/"), datapath.slice(-1)[0]]; }; voided = async () => { return await this.statics({ type: "void" }); }; statics = async (config) => { let addr = `${this.account.physical_address}/__$STATICS/`; let folder = await this.account.manager.ds.folder(addr); let value = config.type === "boolean" ? config.value : "void"; let _id = await this.hash(value); await folder.write({ type: config.type, value, _id }); return { value: addr, _id, type: "address", }; }; err_objects = [ "ZeroDivisionError", "MathError", "SyntaxError", "ValueError", "RuntimeError", "CompileError", "AssertionError", ]; cloth = async (address, options = {}) => { let { just_content } = options; let content; if (address.config) { address = { type: "function", _id: address._id, address: address.value, value: address.value, }; } if (address.type === "address") { if (address.value.includes("/")) { let folder = await this.account.manager.ds.folder(address.value); if (address.object) { folder = await folder.folder(".configs"); } content = await folder.readone({ _id: address._id }); } else if (address.object) { content = { ...address, type: "function" }; } } else if (["function", "class"].includes(address.type)) { if (address._id && address._id === address.value) { content = address; } else { let folder = await this.account.manager.ds.folder(`${address.address}`); folder = await folder.folder(".configs"); content = await folder.readone( address._id ? { _id: address._id } : null ); } } if (just_content) return content; if (content) { content = await this.cloth_content(content); content.address = address.value; if (address.is_literal && content.type === "twain") content.is_literal = true; } return content; }; cloth_content = async (content, options) => { let obj; if (!content) return content; switch (content.type) { case "number": obj = new Num(content, this.account); break; case "string": obj = new Str(content, this.account); break; case "boolean": obj = new Bool(content, this.account); break; case "void": obj = new Voi(content, this.account); break; case "array": obj = new Arr(content, this.account); break; case "twain": obj = new Twa(content, this.account); break; case "instance": obj = new Instance(content, this.account); break; case "function": obj = new Func(content, this.account); break; case "folder": obj = new Fold(content, this.account); break; case "folder_response": obj = new Res(content, this.account); break; case "class": obj = new Cls(content, this.account); break; case "error": obj = new Err(content, this.account); break; default: obj = await this.cloth(content); break; } return await obj.sync(options); }; hash = async (value, alg) => { if (typeof value !== "string") value = JSON.stringify(value); return hash(value, alg); }; } export default Vm_utils;