Published
Edited
Dec 25, 2019
Fork of dType 2
1 fork
Importers
Insert cell
md`# dType 2`
Insert cell
function getLocal(vObj, ndxs, temp){
if (ndxs.length === 0) return temp
return getLocal(vObj, ndxs.slice(1), vObj.value[ndxs[0]])
}
Insert cell
md `# dType`
Insert cell
dT = dT_setTypes(dT_setFunctions({enums:{controls:{}}, enum_choices:{types:[]}, composites:{}, controls:{tuple:{}, array:{}}, t:{}, settings: {
refURL: "http://dTypesite.org/package/#"
}}))
Insert cell
// mutable dTOptions = ({});
Insert cell
mutable tObj = ({value: [ ["0x00", "natural",new BN(55),new BN(55)], [ "0x01aa", "0x01bb"], "balalaika", new BN(1), ()=>{console.log("done!")}], type: { group1: { some:"address", type:"enum:types", signed: "int56", unsigned:"int48"}, somearr:"bytes2[]", name: "string", "sure?":"bool", makeLog:"jsfunction"}})

Insert cell
addType = ({
value: [ "label1", "uint16", new BN(0), new BN(0)],
type: { label:"string", "Component":"enum:types", "x1 from T[x1][x2]":"uint8", "x2 from T[x1][x2]":"uint8"}
})
Insert cell
addType2 = ({
value: ["Lorrr", [ [ "label1", "uint16", new BN(0), new BN(0)], [ "label1", "uint16", new BN(0), new BN(0)]]],
type: {name: "string", components: "type_component[]"}
})
Insert cell
{
yield html `<div id="control3" style="height:500px;"><div id="control2" style="width:50%;"></div><div id="control1" style="width:50%;"></div></div>`
showControl(tObj, "control1", {randomize: true, gui: {align: "left"}, onChange: console.log}) // tObj
showControl(addType, "control2", {gui: {align: "right"}})
}
Insert cell
function showControl(vObj, divId, options = {}){
let div = document.getElementById(divId)
div.innerHTML=""
const DEFAULT_OPTS = {
align: 'left',
theme: {
name: "YoRHa",

colors: {
menuBarBackground: '#CCC8B1',
menuBarText: '#454138',
panelBackground: '#fff', //'#CCC8B1',

componentBackground: '#BAB5A1',
componentBackgroundHover: '#877F6E',
componentForeground: '#454138',
componentActive: '#978F7E',

textPrimary: '#454138',
textSecondary: '#454138',
textHover: '#CCC8B1',
textActive: '#CCC8B1',
},

//Optional
font: {
fontFamily: `Roboto Condensed, helvetica, sans-serif`,
fontSize: '14px',
//fontWeight: '100'
},
},
root: div,
open: true,
barMode: "none",
panelMode: "inner",
width: "50%",
opacity: 0.90,
}
const onChangeSubTyped = (typed) => {
console.log('onChangeSubTyped', typed);
options.onChange(typed);
}
const guiOptions = Object.assign({}, DEFAULT_OPTS, options.gui || {});
let gui = new guify(guiOptions);
const features = options.buttons || [];

if (options.randomize) {
features.push({ type: "button", label: "Randomize", action: () => {
vObj=dT.t.apply(vObj, "random");
showControl(vObj, divId, options);
if (options.onChange) {
options.onChange(vObj);
}
}});
}
if (options.live) {
features.push({ type: "checkbox", label: "Every Change", initial: false});
}
if (options.toast) {
features.push({ type: "button", label: "Toast", action:() => {gui.Toast('Possible error!');}});
}

gui.Register(features);

return dT.t.applyWithCallback(vObj, "showControl", "", gui, onChangeSubTyped);
}
Insert cell
tRand = dT.t.apply(tObj, "random")
Insert cell
// function getRandom(vObj1, divId1, align1){
// vObj1=dT.t.apply(vObj1, "random");
// showControl(vObj1, divId1, align1);
// }
Insert cell
function dT_setFunctions(dT) {
dT.t.applyWithCallback = function(typed, fnName, folder, gui, onChange, ...rest){
// console.log("----- applyWithCallback typed", typed)
// console.log("applyWithCallback fnName, folder", fnName, folder, gui, onChange)
// console.log("applyWithCallback gui", gui)
// console.log("applyWithCallback onChange", onChange)
let name
if (!typed.name) {
typed.name = "."
}
let type =typed.type
let value = typed.value
let temp = {}
let ndx = 0
let fn, ans=[],out={value:[],type:[]}
if (typeof type !== "string") {
if (value instanceof Array)
if (value.length !== Object.keys(type).length) {
return false
}
if (dT.controls.tuple[fnName]) {
folder = dT.controls.tuple[fnName](typed, folder, gui, ...rest)
}
// for (let i in type){
console.log('type', type);
Object.keys(type).forEach((i, nndx) => {
const onChangeSub = typedSub => {
console.log('onChangeSub tuple', nndx, i, typedSub);
if (onChange) {
console.log('---', JSON.stringify(typed.type), JSON.stringify(type));
typed.value[nndx] = typedSub.value;
const typecpy = JSON.parse(JSON.stringify(typed.type));
typecpy[i] = typedSub.type;
// const typedscpy = Object.assign({}, typed, {type: typecpy});
console.log('onChangeSub tuple typed', typecpy, JSON.stringify(typecpy), typed, typed.type, type);
onChange(Object.assign({}, typed, {type: typecpy}));
}
}
temp = {}
temp.value = value[ndx]
temp.type = type[i]
temp.name = i
ans[i] = dT.t.applyWithCallback(temp, fnName, folder, gui, onChangeSub, ...rest)
out.value[ndx]=ans[i].value
out.type[i]=ans[i].type
ndx++
})
return out;
}
let arrT = dT.t.getArrayType({type:type})
console.log(arrT)
if (arrT) {
ans = []
if (dT.controls.array[fnName]) {
folder = dT.controls.array[fnName](typed, folder, gui, ...rest)
}
// for (let i = 0; i<value.length; i++){
value.forEach((val, i) => {
const onChangeSub = (typedSub) => {
console.log('onChangeSub array', i, typedSub);
if (onChange) {
typed.value[i] = typedSub.value;
typed.type[i] = typedSub.type;
console.log('onChangeSub typed', typed);
onChange(typed);
}
}
ans[i] = dT.t.applyWithCallback({value:value[i], type:arrT, name: typed.name+i}, fnName, folder, gui, onChangeSub, ...rest)
out.value.push(ans[i].value)
});
out.type = ans[0].type+"[]"
return out;
}
let compT = dT.t.getComposite(typed.type)
if (compT) {
const onChangeSub = (typedSub) => {
console.log('onChangeSub composite', typedSub);
if (onChange) {
onChange(typedSub);
}
}
return dT.t.applyWithCallback({value:value, type: compT, name: typed.name}, fnName, folder, gui, onChangeSub, ...rest)
}

const onChangeSub = (typedSub) => {
console.log('onChangeSub simple', typedSub);
if (onChange) {
onChange(typedSub);
}
}
let a = dT.t.getFn(fnName, type)(typed, folder, gui, onChangeSub, ...rest)
return a
}
dT.t.apply = function(typed, fnName, folder, ...rest){
//console.log("apply", typed, fnName, folder)
let name
if (!typed.name) {
typed.name = "."
}
let type =typed.type
let value = typed.value
let temp = {}
let ndx = 0
let fn, ans=[],out={value:[],type:[]}
if (!(typeof type == "string")) {
if (value instanceof Array)
if (value.length !== Object.keys(type).length) {
return false
}
if (dT.controls.tuple[fnName]) {
folder = dT.controls.tuple[fnName](typed, folder, ...rest)
}
for (let i in type){
temp = {}
temp.value = value[ndx]
temp.type = type[i]
temp.name = i
ans[i] = dT.t.apply(temp, fnName, folder, ...rest)
out.value[ndx]=ans[i].value
out.type[i]=ans[i].type
ndx++
}
return out;
}
let arrT = dT.t.getArrayType({type:type})
console.log(arrT)
if (arrT) {
ans = []
if (dT.controls.array[fnName]) {
folder = dT.controls.array[fnName](typed, folder, ...rest)
}
for (let i = 0; i<value.length; i++){
ans[i] = dT.t.apply({value:value[i], type:arrT, name: typed.name+i}, fnName, folder, ...rest)
out.value.push(ans[i].value)
}
out.type = ans[0].type+"[]"
return out;
}
let compT = dT.t.getComposite(typed.type)
if (compT) {
return dT.t.apply({value:value, type: compT, name: typed.name}, fnName, folder, ...rest)
}
let a = dT.t.getFn(fnName, type)(typed, folder, ...rest)
return a
}
dT.t.getFn = function(fnName, type) {
if (type.substring(0,4) == "enum") {
return dT.enums.controls[fnName]
}
return dT.controls[type][fnName]
}
dT.t.setType = function (name, test, supertypes= []){
dT[name] = _.NullaryType
(name)
(dT.settings.refURL+name)
(supertypes)
(test)
if (!(dT.enum_choices.types[name]))
dT.enum_choices.types = dT.enum_choices.types.concat([name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT[name]
}
dT.t.setComposite = function (name, tuple){
dT.composites[name] = tuple
dT.controls[name] = dT.controls["tuple"]
if (!(dT.enum_choices.types[name]))
dT.enum_choices.types = dT.enum_choices.types.concat([name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT[name]
}
dT.t.getComposite = function (name){
return dT.composites[name]
}
dT.t.setEnum = function (name, choices){
dT.enums[name] = _.EnumType
(name)
(dT.settings.refURL+name)
(choices);
dT.enum_choices[name]=choices;
if (!(dT.enum_choices.types["enum:"+name]))
dT.enum_choices.types = dT.enum_choices.types.concat(["enum:"+name])
dT.enums.types = _.EnumType
("types")
(dT.settings.refURL+"types")
(dT.enum_choices.types);
return dT.enums[name]
}
dT.t.bnType = function (name, min, max){
let test = x => x.gte(min) &&
x.lte(max)
let supertypes = [dT["bn"]]
dT.controls[name] = Object.assign({},dT.controls["bn"])
dT.controls[name].min(min)
dT.controls[name].max(max)
return dT.t.setType(name, test, supertypes)

}
dT.t.bbnType = function (name, min, max){
let test = x => x.gte(min) &&
x.lte(max)
let supertypes = [dT["bn"]]
dT.controls[name] = Object.assign({},dT.controls["bn"],dT.controls["bbn"])
dT.controls[name].min(min)
dT.controls[name].max(max)
return dT.t.setType(name, test, supertypes)

}
dT.t.byteType = function (name, len){
const re = `0x[a-fA-F0-9]{${len*2}}`
let reg = RegExp(`(?:^${re}$)`)
let test = x => reg.test(x)
let supertypes = [dT["string"]]
dT.controls[name] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;},
random: function(){ return {value: "0x"+("00".repeat(len).replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);})), type:name}},
}
dT.controls[name] = Object.assign({}, dT.controls["string"], dT.controls[name])
dT.controls[name].min("0x"+"00".repeat(len*2))
dT.controls[name].max("0x"+"ff".repeat(len*2))
return dT.t.setType(name, test, supertypes)
}
dT.t.getType = function(typed){
let type = typed.type
if (type.substring(0,4) == "enum") {
return dT.enums[type.substring(5)]
}
if (type.substring(type.length-2) == "[]") {
return _.Array (dT.t.getType({value: null, type: type.substring(0, type.length-2)}))
}
return dT[type];
}
dT.t.getArrayType = function(typed){
let type = typed.type
if (type.substring(type.length-2) == "[]")
return type.substring(0,type.length-2);
return false;
}
dT.t.getComponent = function(typed, key){
let type = typed.type
let value = typed.value
if (type === "tuple") return value[key]
let arrT = dT.t.getArrayType(typed)
if (arrT) {
return {value: value[key], type: arrT, name: typed.name+key}
}
}
dT.t.getRange = function(typed){
let type = typed.type, min, max
if (type.substring(0,4) == "enum") {
min = new BN(0)
max = new BN(dT.enum_choices[type.substring(5)].length-1)
} else {
min = dT.controls[type].min()
max = dT.controls[type].max()
}
return {min: min, max: max}
}
return dT;
}
Insert cell
md `## Set Types`
Insert cell
function dT_setTypes(dT) {
dT["bn"] = _.NullaryType
("bn")
(dT.settings.refURL+"bn")
([])
(x => BN.isBN(x))
dT.controls["bn"] = {
min: function(min){if (min !== undefined) this._min = min; return this._min;},
max: function(max){if (max !== undefined) this._max = max; return this._max;},
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = range.max.sub(new BN(Math.random()*Number.MAX_SAFE_INTEGER).mul(range.max.sub(range.min)).div(new BN(Number.MAX_SAFE_INTEGER)))
return ({value: val, type: type})
},
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'range', label: typed.name+":"+typed.type,
min: dT.controls[typed.type].min().toNumber(),
max: dT.controls[typed.type].max().toNumber(), step: 1 ,
folder: folder,
initial: typed.value.toNumber(),
onChange: (data) => {
typed.value = new BN(data)
if (onChange) onChange(typed);
}
})
return typed
},
}
dT.controls["bbn"] = {
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'text', label: typed.name+":"+typed.type,
folder: folder,
initial: "0x"+typed.value.toString(16),
onChange: (data) => {
console.log(data);
if (data.substring(0, 2) === '0x') {
typed.value = new BN(data.substring(2), 16)
} else {
// TODO: fix type checking in UI
typed.value = new BN(parseInt(data));
}
console.log(typed);
if (onChange) onChange(typed);
}
})
return typed
},

}
dT["string"] = _.NullaryType
("string")
(dT.settings.refURL+"string")
([])
(x => typeof(x) === "string")
dT.controls["string"] = {
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'text', label: typed.name+":"+typed.type,
folder: folder,
initial: typed.value,
onChange: (data) => {
console.log(data);
typed.value = data
console.log(typed);
if (onChange) onChange(typed);
}
})
return typed
},
random: function(typed){
let val = (Math.random()+1).toString(36).substring(Math.random()*23);
typed.value = val
return typed
},
}
dT.controls["natural"] = {
min: function(min){if (min !== undefined) this._min = min; return this._min;},
max: function(max){if (max !== undefined) this._max = max; return this._max;},
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = range.max.sub(Math.random()*Number.MAX_SAFE_INTEGER * range.max.sub(range.min) / Number.MAX_SAFE_INTEGER)
return ({value: val, type: type})
},
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'range', label: typed.name+":"+typed.type,
min: dT.controls[typed.type].min(),
max: dT.controls[typed.type].max(),
step: 1,
folder: folder,
initial: typed.value,
onChange: (data) => {
typed.value = data;
if (onChange) onChange(typed);
}
})
return typed
},
}

dT.enums.controls = {
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'select', label: typed.name+":"+typed.type,
options: dT.enum_choices[typed.type.substring(5)],
folder: folder,
initial: typed.value,
onChange: (data) => {
console.log(data);
typed.value = data
console.log(typed);
if (onChange) onChange(typed);
}
})
return typed
},
random: function(typed){
let type = typed.type
let range = dT.t.getRange(typed)
let val = new BN(Math.random()*Number.MAX_SAFE_INTEGER).mul(range.max.sub(range.min)).div(new BN(Number.MAX_SAFE_INTEGER))
val = val.toNumber()
val = dT.enum_choices[type.substring(5)][val]
typed.value = val
return typed
}
}
dT.controls.tuple = {
showControl: function(typed, folder, gui, onChange){
let fold1 = folder+"."+typed.name
gui.Register(
{
type: 'folder',
label: fold1,
folder: folder,
open: true
})
return fold1
},
random: function(value, type){
let ndx = 0, temp, ans =[], out={value:[],type:{}}
for (let i in type){
temp = {}
temp.value = value[ndx]
temp.type = type[i]
temp.name = i
ans[i] = dT.t.apply(temp, "random")
out.value[ndx]=ans[i].value
out.type[i]=ans[i].type
ndx++
}
return out
}
}
dT.t.setComposite("type_component", { label:"string", "Component":"enum:types", "[x1]":"uint8", "[x2]":"uint8"})

dT.controls.array = {
showControl: dT.controls.tuple.showControl ,
random: (typed)=>{typed},
}
dT["tuple"] = _.Array (_.Unknown)
dT.t.setType("integer", x=> Math.floor(x) == x , [])
dT.t.setType("natural", x=> x >=0 , [dT["integer"]])
let min = 0, max = Number.MAX_SAFE_INTEGER
dT.t.setType("ctrlrange", x=> x >= min && x <= max, [dT["natural"]])
dT.controls["ctrlrange"] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;}
}
dT.controls["ctrlrange"].min(min)
dT.controls["ctrlrange"].max(max)
dT.t.setType("ctrllinear", x=> x >= min && x <= Math.PI, [])
dT.controls["ctrllinear"] = {
min: function(min){if (min) this._min = min; return this._min;},
max: function(max){if (max) this._max = max; return this._max;}
}
dT.controls["ctrllinear"].min(min)
dT.controls["ctrllinear"].max(Math.PI)

dT.t.setEnum("functions", [
"x=>x",
"x=>x(x)",
"(x,y)=>x",
"(x,y)=>y",
"(x,...y)=>y",
"(x,y,z)=>x(y(z))",
"(x,y,z)=>[x, z, y]",
"(x,y)=>[x, y, y]",
"x=>Math.sin(x)",
"x=>Math.cos(x)",
"x=>x*2",
"x=>x*x",
"(x,y)=>y.map(x)",
"x=>x+1",
"x=>x-1",
"x=>1/x",
"x=>0-x",

"x=>Math.sin(x)",
"x=>Math.cos(x)",
"x=>Math.tan(x)",
"x=>Math.sqrt(x)",
"x=>Math.exp(x)",
"x=>Math.log(x)",
"x=>Math.abs(x)",
"x=>Math.floor(x)",
])
S.map (((y)=>{
if (y < 7) {
dT.t.bnType( "uint"+y*8, new BN(0), new BN(2).pow(new BN(y*8)))
dT.t.bnType( "int"+y*8, new BN(2).pow(new BN(y*8-1)).neg(), new BN(2).pow(new BN(y*8-1)))
} else {
dT.t.bbnType( "uint"+y*8, new BN(0), new BN(2).pow(new BN(y*8)))
dT.t.bbnType( "int"+y*8, new BN(2).pow(new BN(y*8-1)).neg(), new BN(2).pow(new BN(y*8-1)))
}
dT.t.byteType("bytes"+y, y)
})) (S.range (1) (33));
let types = [
["object", _.Object],
["function", _.Any],
["address", "bytes20"],
["byte", "bytes1"],
["uint", "uint256"],
["int", "int256"],
["bool", "uint8"],
["tuple", _.Any], // may be better defined? _.RecordType
["any", _.Any],
["jsfunction", _.AnyFunction],
]
types.map(x=>{
if (x[1] in dT.controls) {
dT.t.setType(x[0], x=>true,[dT[x[1]]])
dT.controls[x[0]] = dT.controls[x[1]]
} else {
dT.t.setType(x[0], x=>true,[x[1]])
}
})
dT.controls.bool = {
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'checkbox', label: typed.name,
folder: folder,
initial: typed.value.gt(new BN(0)),
onChange: (data) => {
console.log(data);
typed.value = data
console.log(typed);
if (onChange) onChange(typed);
}
})
return typed
},
random: function(typed){
let type = typed.type
let val = new BN(Math.round(Math.random()))
console.log(val.toNumber())
typed.value = val
return typed
}
}
dT.controls.jsfunction = {
showControl: function(typed, folder, gui, onChange){
gui.Register({
type: 'button', label: typed.name,
folder: folder,
action: typed.value
})
return typed
},
random: function(typed){
return typed
}
}
return dT;
}
Insert cell
md `## Imports`
Insert cell
guify = require('guify@0.12.0/lib/guify.min.js');
Insert cell
BN = require('https://bundle.run/bn.js@4.11.8');

//require('bn.js@5.0.0/lib/bn.js').catch(() => window["gYNtmMJ"])
Insert cell
S = require ('sanctuary');
Insert cell
_ = require ('sanctuary-def');
Insert cell
html`<link href="https://fonts.googleapis.com/css?family=Roboto+Condensed&display=swap" rel="stylesheet">`
Insert cell
FontFaceObserver = require('https://bundle.run/fontfaceobserver@2.1.0')
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more