UNPKG

godprotocol

Version:

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

585 lines (501 loc) 16.2 kB
import { generate_random_string } from "generalised-datastore/utils/functions.js"; class Storage { constructor(account) { this.account = account this.methods = { 'get_id': {args:[], ret: ['_id', 'string']}, 'folder': {args:[['address', 'string'], ['options', 'twain']], ret: ['folder', 'folder']}, '__and__': {args: [['other', 'object']], ret: ['result', 'object']}, '__sub__': {args: [['other', 'object']], ret: ['result', 'object']}, '__or__': {args: [['other', 'object']], ret: ['result', 'object']}, '__add__': {args: [['other', 'object']], ret: ['result', 'object']}, '__mul__': {args: [['other', 'object']], ret: ['result', 'object']}, '__div__': {args: [['other', 'object']], ret: ['result', 'object']}, '__gt__': {args: [['other', 'object']], ret: ['result', 'object']}, '__lt__': {args: [['other', 'object']], ret: ['result', 'object']}, '__gte__': {args: [['other', 'object']], ret: ['result', 'object']}, '__lte__': {args: [['other', 'object']], ret: ['result', 'object']}, '__ne__': {args: [['other', 'object']], ret: ['result', 'object']}, '__eq__': {args: [['other', 'object']], ret: ['result', 'object']}, } } __or__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value || other break case 'string': result = this.value || other break case 'void': result = await other.to_address() break case 'function': result = await this.to_address() break case 'instance': result = await this.run('__or__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __and__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value && other break case 'instance': result = await this.run('__and__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __gt__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value > other break case 'instance': result = await this.run('__gt__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __gte__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value >= other break case 'instance': result = await this.run('__gte__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __lt__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value < other break case 'instance': result = await this.run('__lt__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __lte__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value <= other break case 'instance': result = await this.run('__lte__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __eq__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value == other break case 'string': result = this.value == other break case 'class': result = this.ref() === other.ref() break case 'function': result = this.ref() === other.ref() break case 'instance': await this.run('__eq__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (result == null) result = await this.account.vm.voided() return result } __ne__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value != other break case 'void': result = other.type === 'void' break case 'class': result = this.ref() !== other.ref() break case 'function': result = this.ref() !== other.ref() break case 'instance': result = await this.run('__ne__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (result==null) result = await this.account.vm.voided() return result } __div__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value / other break case 'instance': result = await this.run('__div__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __mul__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value * other break case 'string': if (typeof other === 'string') result = await this.repeat(other) break; case 'instance': result = await this.run('__mul__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __sub__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value - other break case 'instance': result = await this.run('__sub__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } __add__ = async(other)=>{ let result; switch(this.type){ case 'number': if (typeof other === 'number') result = this.value + other break case 'string': if (typeof other === 'string') result = await this.concat(other) break; case 'instance': result = await this.run('__add__', {config: {arguments: [other], location: this.spawn_address()}, chain: this.account.chain}) break; } if (!result) result = await this.account.vm.voided() return result } _folder = async(options={})=>{ let addr = this.type === 'folder'? this.config.value: this.address let folder = await this.account.manager.ds.folder(addr, {...options}) return folder; } emit = async(name, args)=>{ name = await name.literal() if(this.type === 'instance'){ name = `${name}:${this.config._id}` } let fold = await this._folder() let res = await fold.emit(name, args[1]? [await args[1].to_address()]: [], {account: this.account}) let {vm, chain} = this.account return await vm.instantiate({ type: 'array', value: res, location: vm.gen_location() }, {chain}) } listen = async(name, args)=>{ name = await name.literal() let func = await args[1].to_address() if (this.type === 'instance'){ name = `${name}:${this.config._id}` } let fold = await this._folder() await fold.listen(name, func, {account: this.account}) } folder = async(address, args, {call_config, chain})=>{ let parent = this.config.location if (this.type === 'instance'){ parent = `${this.config.cls}/${this.config._id}` } let fold = await this.account.manager.ds.folder(parent, {account: this.account.physical_address}) address = await address.literal() let subfolder = await fold.folder(address, {account: this.account.physical_address}) let obj = { type: 'folder', value: subfolder.address, location: call_config.location } let folder = await chain.folder(call_config.location) let res = await folder.write(obj) return { type: 'address', value: folder.address, _id: res._id } } get_id = async()=>{ return this.config._id } call = async(method, options)=>{ let {chain, call_config, pure, thread} = options let {arguments: args} = call_config, other, result; let method_name = method; let args_ = new Array() for(let a=0; a < args.length; a++){ args_[a] = await this.account.vm.cloth(args[a]) } args = args_ switch(this.type){ case 'number': this.value = await this.literal() other = args[0] && await args[0].literal() method = this[method] if (typeof method === 'function'){ result = await method(other, args, {call_config, thread, chain}) } break; case 'string': this.value = await this.literal() other = args[0] && await args[0].literal() method = this[method] if (typeof method === 'function'){ result = await method(other, args, {call_config}) }else { result = await this.overloads(method_name, other, args, {call_config, thread, chain}) } break; case 'array': if (method === 'call') method = 'call_' method = this[method] if(typeof method === 'function'){ result = await method(args[0], args, {call_config, thread, chain}) } break; case 'twain': if(['set', 'get'].includes(method)){ method = `${method}_` } method = this[method] if (typeof method === 'function'){ result = await method(args[0], args, {call_config, thread, chain}) } break; case 'function': method = this[method] if (typeof method === 'function'){ result = await method(args[0], args, {call_config, thread, chain}) } break; case 'instance': method = this[method] if(typeof method === 'function'){ result = await method(args[0], args, {call_config, chain}) } break; case 'class': method = this[method] if (typeof method === 'function'){ result = await method(args[0], args, {call_config, thread, chain}) } break; default: method = this[method] if (typeof method === 'function'){ result = await method(args[0], args, {call_config, thread, chain}) } ; } if(pure){ return result; } if (result && result.__interrupt__){} else if (result && ['address', 'folder'].includes(result.type)){ }else result = await this.account.vm.parse_aircode(result, { config: call_config, chain }) return result } overloads = async (name, other, args)=>{ let lit = await this.literal(), result; switch(this.type){ case "string": switch(name){ case '__eq__': result = lit === other break; case '__ne__': result = lit !== other break; case '__lt__': result = lit < other; break; case '__lte__': result = lit <= other; break; case '__gt__': result = lit > other; break; case '__or__': result = lit || other; break; case '__and__': result = lit && other; break; case '__gte__': result = lit >= other; break; case '__mul__': result = await this.repeat(other, args) break; case '__add__': result = await this.concat(other, args) break } break; } return result } ref = ()=>{ return `${this.address || this.config.address}/${this.config._id}` } get_ =async(prop)=>{ if (!this.methods[prop] && !this[prop]) return; return { type: 'address', object: this.ref(), value: prop } } get = async(prop, options={})=>{ let {obj, raw} = options let result; if (this.type === 'twain' && this.is_literal){ if (Object.keys(this.methods).includes(prop)){ return { type: 'address', value: prop, object: this.ref() } } } if (this.account.vm.datatypes.includes(this.type) || this.type === 'error' || ['function', 'class'].includes(this.type)){ if(this.type === 'void' && !Object.keys(this.methods).includes(prop)){ result = await this.account.vm.throw_error({type: "ValueError", message: "Cannot subset a void value"}) } else if(this.type === 'function'){ result = await this.get_(prop) } else if (this.type === 'twain'){ result = await this.get_(prop) }else if (options.obj && options.obj.type === 'number' && ['array', 'string'].includes(this.type)){ if (this.type === 'array') result = await this.index(prop) else { result = await this.call('index', { chain: this.account.chain, call_config: {arguments: [options.config], location: this.spawn_address()} }) } } else if (!prop.includes('/')){ if (this.methods[prop]) result = { type: 'address', value: prop, object: this.ref() } if (['function', 'class'].includes(this.type)){ result.config = true; } } }else if(this.type === 'instance'){ result = await this.get_(obj? await obj.literal() :prop) } else if(this.type === 'folder'){ result = await this.get_(obj? await obj.literal() : prop) } if (!result && !raw){ result = await this.account.vm.statics({type:'void'}) } return result } set = async(prop, value, options)=>{ let {chain} = options; if (this.type === 'twain'){ await this.call('set', {call_config: {arguments: [prop, value], location: this.spawn_address()}, chain}) }else if(this.type === 'instance' || this.type === 'function'){ return await this.set_(prop, value) } } chain =async ()=>{ if (this.chn || !this.address)return this.chn; this.chn = await this.account.chain.chain(this.address) return this.chn } sync = async()=>{ return this } spawn_address = (spw)=>{ return `${this.address}_${spw || Math.random().toString().slice(3)}` } _split_datapath = (datapath)=>{ datapath = datapath.split('/') return [datapath.slice(0,-1).join('/'), datapath.slice(-1)[0]] } to_address = async()=>{ let o = { type: 'address', value: this.address || this.config.location, _id: this.config._id, } if (this.value && this.value.object) o.object = this.value.object if (['function', 'class'].includes(this.type)){ o.config = true o.value = this.config.address } o.module = this.config.module if (this.is_literal) { o.is_literal = true } return o } sync = async()=>{ return this } } export default Storage;