Skip to content
Snippets Groups Projects
typeset.js 20.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jake Read's avatar
    Jake Read committed
    // typeset: functional types -> bytes for js -> embedded sys
    
    Jake Read's avatar
    Jake Read committed
    // bless up @ modern js https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
    
    
    Jake Read's avatar
    Jake Read committed
    let tsdebug = false
    
    Jake Read's avatar
    Jake Read committed
    // oy,
    
    Jake Read's avatar
    Jake Read committed
    const checkKey = (type, arr, start) => {
    
    Jake Read's avatar
    Jake Read committed
      if (arr[start] !== type.key) {
        console.log('erroneous bytes')
        console.log(arr)
        throw new Error(`mismatched key on phy read: for ${type.name}, find ${arr[start]} instead of ${type.key} ... at ${start} index`)
      }
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkBoolean = (value) => {
    
      if (typeof value !== 'boolean')
        throw new Error('cannot cast non-boolean to bool at phy')
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkNumber = (value) => {
    
      if (typeof value !== 'number')
        throw new Error(`cannot cast non-number into physical world "${value}", ${typeof value}`)
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkString = (value) => {
    
      if (typeof value !== 'string')
        throw new Error(`cannot cast non-string to string at phy! "${value}", "${typeof value}"`)
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkArray = (thing) => {
    
      if (!Array.isArray(thing))
        throw new Error('this thing is not an array!')
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkUnsigned = (value, bits) => {
    
      if (value > Math.pow(2, bits))
        throw new Error('value out of byte bounds')
    
    Jake Read's avatar
    Jake Read committed
    }
    
    const checkSigned = (value, bits) => {
    
    Jake Read's avatar
    Jake Read committed
      let comparator = Math.pow(2, bits - 1)
    
      if (value > comparator || value < -comparator)
        throw new Error('value out of byte bounds')
    
    Jake Read's avatar
    Jake Read committed
    }
    
    Jake Read's avatar
    Jake Read committed
    const findPhy = (type) => {
      let phy = TSET.find((cand) => {
        return cand.name === type
      })
    
      if (phy === undefined)
    
        // try this... catch err elsewhere
    
        throw new Error(`could not find phy for datatype: ${type}`)
    
    Jake Read's avatar
    Jake Read committed
      return phy
    }
    
    
    const bounds = (value, min, max) => {
      return Math.max(min, Math.min(value, max))
    }
    
    const intBounds = (pfloat, min, max) => {
      return Math.round(bounds(pfloat, min, max))
    }
    
    // TYPES:
    /*
    name: string identifier, how we 'specify' what an input / output / state is
    key: byte-code for the network. if this, write, and read, don't exist, link can't have one
    write: serialize into bytes
    read: deserialize
    copy: move about within js,
     copies are 'outgoing' ... so typeA.copy.typeB(value) turns the value from
     typeA -> typeB
     the standard is typeA.copy.typeA(value), this is just a memory shuffle
     for the sake of dereferencing: we can write our own types per item
    */
    
    // TODO: TYPES:
    /*
    we are still not really type-checking on calls to .put(), and should be...
    there is probably a slick, clean way to do this
    also: would really like to work with typedarrays where they are appropriate
    
    
    .. *could* imagine some hairbrain walk through these things: if we have, i.e., conversion
    from string -> number written, and from number -> uint8, we should be able to
    compose a tree of these on the fly ...
    
    */
    
    const TSET = [
      {
    
    Jake Read's avatar
    Jake Read committed
        name: 'boolean',
    
    Jake Read's avatar
    Jake Read committed
        write: function(value) {
    
    Jake Read's avatar
    Jake Read committed
          checkBoolean(value)
    
    Jake Read's avatar
    Jake Read committed
          let rtarr = [this.key]
    
    Jake Read's avatar
    Jake Read committed
          if (value) {
    
    Jake Read's avatar
    Jake Read committed
            rtarr.push(1)
    
    Jake Read's avatar
    Jake Read committed
          } else {
    
    Jake Read's avatar
    Jake Read committed
            rtarr.push(0)
          }
          return rtarr
        },
    
    Jake Read's avatar
    Jake Read committed
        read: function(arr, start) {
          checkKey(this, arr, start)
    
    Jake Read's avatar
    Jake Read committed
          if (arr[start + 1] === 1) {
    
    Jake Read's avatar
    Jake Read committed
          } else if (arr[start + 1] === 0) {
    
    Jake Read's avatar
    Jake Read committed
          } else {
    
            throw new Error(`non std boolean byte, ${arr[start + 1]}`)
    
    Jake Read's avatar
    Jake Read committed
          }
    
          return {item: item, increment: 2}
        },
        copy: {
          boolean: function(bool) {
            return bool // direct: a basic js type, so we just pass it on
          },
          number: function(bool) { // converts boolean -> numbers
            if (bool) {
              return 1
            } else {
              return 0
            }
    
    Jake Read's avatar
    Jake Read committed
        }
    
      }, { // booleanArray: 33,
    
    Jake Read's avatar
    Jake Read committed
        name: 'byte',
        key: 34,
        write: function(value) {
          checkNumber(value)
          checkUnsigned(value, 8)
          return [this.key, value]
        },
        read: function(arr, start) {
          checkKey(this, arr, start)
          return {
            item: arr[start + 1],
            increment: 2
          }
    
        },
        copy: {
          byte: function(byte) {
            return byte
          }
    
    Jake Read's avatar
    Jake Read committed
        }
    
      }, {
    
    Jake Read's avatar
    Jake Read committed
        name: 'byteArray',
        key: 35,
        write: function(value) {
          checkArray(value)
          let rtarr = writeLenBytes(value.length).concat(value)
          rtarr.unshift(this.key)
    
          if (tsdebug)
            console.log('byteArray sanity check:', value, 'written as:', rtarr)
    
    Jake Read's avatar
    Jake Read committed
          return rtarr
        },
        read: function(arr, start) {
          checkKey(this, arr, start)
          let lb = readLenBytes(arr, start + 1)
          let narr = new Array()
    
    Jake Read's avatar
    Jake Read committed
          for (let i = 0; i < lb.len; i++) {
    
    Jake Read's avatar
    Jake Read committed
            narr.push(arr[start + 1 + lb.numBytes + i])
          }
          return {
            item: narr,
            increment: lb.len + lb.numBytes + 1
          }
    
        copy: { // copy:  into another bytearray
    
          byteArray: function(arr) {
            // TODO would be making bytearrays into buffers, would speed this up ...
            let ret = new Array(arr.length)
            for (let item in arr) {
              ret[item] = arr[item]
            }
            return ret
    
          },
          reference: function(arr){
            let ret = new Array(arr.length)
            for (let item in arr) {
              ret[item] = arr[item]
            }
            return ret
    
    Jake Read's avatar
    Jake Read committed
        }
    
      }, { // char 36, string 37,
    
        name: 'string',
    
    Jake Read's avatar
    Jake Read committed
        key: 37,
        write: function(str) {
          checkString(str)
    
          let rtarr = new Array()
    
    Jake Read's avatar
    Jake Read committed
          for (let i = 0; i < str.length; i++) {
    
            rtarr.push(str.charCodeAt(i))
          }
          // length bytes are 7-bit 'msb for continue' numbers ...
    
    Jake Read's avatar
    Jake Read committed
          // the -1 because we are not counting the length of the key
    
          let lb = writeLenBytes(rtarr.length)
          rtarr = lb.concat(rtarr)
          rtarr.unshift(this.key)
          return rtarr
        },
        read: function(arr, start) {
    
    Jake Read's avatar
    Jake Read committed
          checkKey(this, arr, start)
    
          let lb = readLenBytes(arr, start + 1)
    
    Jake Read's avatar
    Jake Read committed
          //console.log('lenbytes', lb)
    
          let str = new String()
    
    Jake Read's avatar
    Jake Read committed
          for (let i = 0; i < lb.len; i++) {
    
    Jake Read's avatar
    Jake Read committed
            str += String.fromCharCode(arr[start + 1 + lb.numBytes + i])
          }
          return {
            item: str,
            increment: lb.len + lb.numBytes + 1
    
        },
        copy: {
          string: function(str) {
    
    Jake Read's avatar
    Jake Read committed
            return str
    
          },
          number: function(str) {
            return parseFloat(str)
          },
          boolean: function(str){
            if(str == true){
              return true
            } else {
              return false
            }
    
    Jake Read's avatar
    Jake Read committed
          },
          reference: function(str){
            return str
    
      }, {
    
        name: 'uint8',
    
    Jake Read's avatar
    Jake Read committed
        key: 38,
    
        write: function(value) {
    
    Jake Read's avatar
    Jake Read committed
          checkNumber(value)
          checkUnsigned(value, 8)
    
          if (value > 255 || value < 0)
            throw new Error('num too large to represent with cast type, will contencate')
            // dont' need to type-buffer this,
    
          let rtarr = [this.key, value]
          return rtarr
        },
    
    Jake Read's avatar
    Jake Read committed
        read: function(arr, start) {
    
          // assume we're reading out of an array
          // start[] should === key
    
          if (arr[start] !== this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
          if (arr[start + 1] > 255 || arr[start + 1] < 0)
            throw new Error('whaky read-in on uint8')
    
          return {
    
    Jake Read's avatar
    Jake Read committed
            item: arr[start + 1],
    
            increment: 2
          }
    
        },
        copy: {
          uint8: function(uint8){
            // by clamping at the copy, we can reduce complexity at read and write ?
            // and improve clarity elsewhere ...
            return bounds(uint8, 0, 255) // clamp number
          },
          uint16: function(uint8){
            // because we always copy-in before copying-out (to other types)
            // we don't have to clamp here again, that's nice.
            // but would to go down to a smaller value ...
            return uint8
          },
          uint32: function(uint8){
            // this could really get exhaustive,
            return uint8
    
          },
          number: function(uint8){
            return uint8
    
      }, { // uint8Array 39
    
    Jake Read's avatar
    Jake Read committed
        key: 40,
    
          if (typeof value !== 'number')
            throw new Error(`cannot cast non-number into physical world "${value}", ${typeof value}`)
          if (value > 65536 || value < 0)
            throw new Error('num too large to represent with cast type, will contencate')
    
          let tparr = new Uint16Array(1)
          tparr[0] = value
          let btarr = new Uint8Array(tparr.buffer)
          //place
    
          let rtarr = Array.from(btarr)
    
    Jake Read's avatar
    Jake Read committed
        read: function(arr, start) {
    
          // assume we're reading out of an array
          // start[] should === key
    
          if (arr[start] !== this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
    
          let rdarr = arr.slice(start + 1, start + 3)
    
          if (tsdebug)
            console.log('bytes on read of uint16 (little eadian)', btarr)
            // now make uint32 view on this ...
    
          let vlarr = new Uint16Array(btarr.buffer)
    
          if (tsdebug)
            console.log('vlarr', vlarr)
          return {item: vlarr[0], increment: 3}
        },
        copy: {
          uint16: function(uint16){
            return bounds(uint16, 0, 65535)
          },
          uint8: function(uint16){
            return bounds(uint16, 0, 255)
    
          },
          number: function(uint16){
            return uint16
    
      }, { // uint16 array 41
    
    Jake Read's avatar
    Jake Read committed
        name: 'uint32',
    
    Jake Read's avatar
    Jake Read committed
        key: 42,
    
    Jake Read's avatar
    Jake Read committed
        write: function(value) {
    
          if (typeof value !== 'number')
            throw new Error(`cannot cast non-number into physical world "${value}", ${typeof value}`)
          if (value > 4294967296)
            throw new Error('num too large to represent with cast type, will contencate')
    
    Jake Read's avatar
    Jake Read committed
          let tparr = new Uint32Array(1)
          tparr[0] = value
          let btarr = new Uint8Array(tparr.buffer)
    
          let rtarr = Array.from(btarr)
    
          rtarr.unshift(this.key)
    
          if (tsdebug)
            console.log("UINT32 WRITES ARR: ", rtarr, "FOR: ", value)
    
          return rtarr
    
    Jake Read's avatar
    Jake Read committed
        },
    
        read: function(arr, start) {
    
          // assume we're reading out of an array
          // start[] should === key
    
          if (arr[start] !== this.key) {
            console.log("erroneous bytes:", arr)
            console.log("error at byte:", start, "is", arr[start])
            console.log("expected key:", this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
          }
    
          let rdarr = arr.slice(start + 1, start + 5)
    
          let btarr = Uint8Array.from(rdarr)
    
          if (tsdebug)
            console.log('bts on read of uint32', btarr)
            // now make uint32 view on this ...
    
          let vlarr = new Uint32Array(btarr.buffer)
    
          if (tsdebug)
            console.log("UINT32 READ ARR: ", vlarr[0], "FROM: ", btarr)
          if (tsdebug)
            console.log('vlarr', vlarr)
          return {item: vlarr[0], increment: 5}
        },
        copy: {
          uint32: function(uint32){
            return bounds(uint32, 0, 4294967295)
    
          },
          number: function(uint32){
            return uint32
    
    Jake Read's avatar
    Jake Read committed
        }
    
    Jake Read's avatar
    Jake Read committed
      }, // uint32array 43,
      /*
      uint64 44, uint64array 45,
      int8 46, int8array 47,
      int16 48, int16array 49,
      int32 50, int32array 50,
    
    Jake Read's avatar
    Jake Read committed
      */
      {
        name: 'int32',
        key: 50,
        write: function(value) {
    
          if (typeof value !== 'number')
            throw new Error(`cannot cast non-number into physical world "${value}", ${typeof value}`)
    
    Jake Read's avatar
    Jake Read committed
          let tparr = new Int32Array(1)
          tparr[0] = value
          let btarr = new Uint8Array(tparr.buffer)
          //place
          let rtarr = Array.from(btarr)
          rtarr.unshift(this.key)
    
          if (tsdebug)
            console.log("INT32 WRITES ARR: ", rtarr, "FOR: ", value)
    
    Jake Read's avatar
    Jake Read committed
          return rtarr
        },
        read: function(arr, start) {
          // assume we're reading out of an array
          // start[] should === key
    
          if (arr[start] !== this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
    
    Jake Read's avatar
    Jake Read committed
          let rdarr = arr.slice(start + 1, start + 5)
          let btarr = Uint8Array.from(rdarr)
    
          if (tsdebug)
            console.log('bts on read of uint32', btarr)
            // now make uint32 view on this ...
    
    Jake Read's avatar
    Jake Read committed
          let vlarr = new Int32Array(btarr.buffer)
    
          if (tsdebug)
            console.log("UINT32 READ ARR: ", vlarr[0], "FROM: ", btarr)
          if (tsdebug)
            console.log('vlarr', vlarr)
          return {item: vlarr[0], increment: 5}
        },
        copy: {
          int32: function(int32){
            return bounds(int32, -2147483647, 2147483647)
    
          },
          number: function(int32){
    
            return int32
    
    Jake Read's avatar
    Jake Read committed
      int64 52, int64array 53,
      float32 54, float32array 55,
      float64 56, float64array 57 (these are === javascript 'numbers') ... how to alias ?
      */
    
    Jake Read's avatar
    Jake Read committed
      {
        name: 'number',
    
    Jake Read's avatar
    Jake Read committed
        key: 56,
        write: function(value) {
    
          if (typeof value !== 'number')
            throw new Error(`cannot cast non-number into physical world "${value}", ${typeof value}`)
    
    Jake Read's avatar
    Jake Read committed
          let tparr = new Float64Array(1)
          tparr[0] = value
          let btarr = new Uint8Array(tparr.buffer)
          // place
    
          let rtarr = Array.from(btarr)
    
    Jake Read's avatar
    Jake Read committed
          rtarr.unshift(this.key)
          return rtarr
        },
    
    Jake Read's avatar
    Jake Read committed
        read: function(arr, start) {
    
          if (arr[start] !== this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
    
          let rdarr = arr.slice(start + 1, start + 9)
    
    Jake Read's avatar
    Jake Read committed
          let btarr = Uint8Array.from(rdarr)
    
          if (tsdebug)
            console.log('bts on read of float64', btarr)
    
    Jake Read's avatar
    Jake Read committed
          let vlarr = new Float64Array(btarr.buffer)
    
          if (tsdebug)
            console.log('vlarr', vlarr)
          return {item: vlarr[0], increment: 9}
        },
        copy: {
          number: function(num){
            return num
          },
          boolean: function(num){
            if(num > 0){
              return true
            } else {
              return false
            }
          },
          uint8: function(num){
            return intBounds(num, 0, 255)
          },
          uint16: function(num){
            return intBounds(num, 0, 65535)
          },
          uint32: function(num){
            return intBounds(num, 0, 4294967295)
          },
          int32: function(num){
            return intBounds(num, -2147483647, 2147483647)
    
    Jake Read's avatar
    Jake Read committed
          }
        }
    
    Jake Read's avatar
    Jake Read committed
      },
    
    Jake Read's avatar
    Jake Read committed
      { // cuttlefish only, not a real pass
        name: 'reference',
        copy: {
          reference: function(ref){
            let type = typeof ref
            if(type === 'string' || type === 'number' || type === 'boolean'){
              console.error('cannot pass core types as a reference')
              return null
            } else {
              return ref
            }
          }
        }
      },
    
    Jake Read's avatar
    Jake Read committed
      {
        name: 'object',
        copy: {
          object: function(obj){
            return JSON.parse(JSON.stringify(obj))
          }
        }
      },
    
    Jake Read's avatar
    Jake Read committed
      { // cuttlefish only, so no key, read or write fn's
        // this is : https://developer.mozilla.org/en-US/docs/Web/API/ImageData
        name: 'ImageData',
        copy: {
          ImageData: function(imageData){
            return new ImageData(
              new Uint8ClampedArray(imageData.data),
              imageData.width,
              imageData.height
            ) //
    
    Jake Read's avatar
    Jake Read committed
          },
          reference: function(imageData){
            return imageData
    
    Jake Read's avatar
    Jake Read committed
          }
        }
    
      },
      {
        name: 'Float32Array',
        copy: {
          Float32Array: function(float32Array) {
            return float32Array.slice();
          }
        }
      },
      {
        name: 'array',
        copy: {
    
          array: (arr) => [...arr],
          reference: (arr) => {
    
    Jake Read's avatar
    Jake Read committed
            return arr
    
    Jake Read's avatar
    Jake Read committed
      },
      {
        name: 'MDmseg',
    
    Jake Read's avatar
    Jake Read committed
        key: 88,
        write: function(ms) {
          // ok, bless up, we have:
          /*
          p0: 3-arr
          p1: 3-arr
          t: num
          v0: num
          a: num
          // for simplicity, we should write one typedarray
          */
          let f32arr = Float32Array.from([
            ms.p0[0], ms.p0[1], ms.p0[2],
            ms.p1[0], ms.p1[1], ms.p1[2],
            ms.t, ms.v0, ms.a]
          )
          // ok,
          let btarr = new Uint8Array(f32arr.buffer)
          let rtarr = Array.from(btarr)
          rtarr.unshift(this.key)
          return rtarr
        },
        read: function(arr, start) {
          /*
          if (arr[start] !== this.key)
            throw new Error(`mismatched key on phy read: ${arr[start]}, ${this.key}`)
          let rdarr = arr.slice(start + 1, start + 9)
          let btarr = Uint8Array.from(rdarr)
          if (tsdebug)
            console.log('bts on read of float64', btarr)
          let vlarr = new Float64Array(btarr.buffer)
          if (tsdebug)
            console.log('vlarr', vlarr)
          return {item: vlarr[0], increment: 9}
          */
        },
    
    Jake Read's avatar
    Jake Read committed
        copy: {
          MDmseg: (mdmseg) => {
            return {
              p0: mdmseg.p0,
              p1: mdmseg.p1,
              t: mdmseg.t,
              v0: mdmseg.v0,
              a: mdmseg.a
            }
          },
          reference: (mdmseg) => {
            return mdmseg
          }
        }
    
    Jake Read's avatar
    Jake Read committed
      }
    
    Jake Read's avatar
    Jake Read committed
      // etc
    
    Jake Read's avatar
    Jake Read committed
    ] // end TSET
    
    let intTypes = [
    
      'uint8',
      'uint16',
      'uint32',
      'uint64',
      'int8',
      'int16',
      'int32',
      'int64'
    
    Jake Read's avatar
    Jake Read committed
    ]
    
    Jake Read's avatar
    Jake Read committed
    
    
    let floatTypes = ['number']
    
    Jake Read's avatar
    Jake Read committed
    const isIntType = (type) => {
    
    Jake Read's avatar
    Jake Read committed
      for (let t of intTypes) {
    
        if (type == t)
          return true
    
    Jake Read's avatar
    Jake Read committed
      }
      return false
    }
    
    
    const isFloatType = (type) => {
    
    Jake Read's avatar
    Jake Read committed
      for (let t of floatTypes) {
    
        if (type == t)
          return true
    
      }
      return false
    }
    
    const isNumType = (type) => {
    
      if (isIntType(type))
        return true
      if (isFloatType(type))
        return true
    
    const writeLenBytes = (len) => {
      // return array of len bytes for this number
      let bts = new Array()
    
    Jake Read's avatar
    Jake Read committed
      if (len > 65536) {
    
    Jake Read's avatar
    Jake Read committed
        throw new Error('cannot write length bytes for len > 2^16')
      } else {
    
        // this is little eadian ... right ?
    
    Jake Read's avatar
    Jake Read committed
        bts.push(len & 255);
    
        bts.push((len >> 8) & 255);
    
    Jake Read's avatar
    Jake Read committed
      }
      // here to check,
    
      //if(len > 255){
      //  console.log(`LEN > 255: writes len bytes `, bts[0], bts[1], 'for', len)
      //}
    
      return bts
    }
    
    Jake Read's avatar
    Jake Read committed
    
    
    const readLenBytes = (arr, start) => {
      // need 2 know how many to increment as well,
    
      let len = (arr[start + 1] << 8) | arr[start]
    
    Jake Read's avatar
    Jake Read committed
      // still interested in this,
    
      //if(len > 255){
      //  console.log(`LEN > 255: reads len bytes `, arr[start], arr[start+1], 'for len', len)
      //}
    
      return {len: len, numBytes: 2}
    
    Jake Read's avatar
    Jake Read committed
    // heavy mixin of functional programming
    const MSGS = {
    
    Jake Read's avatar
    Jake Read committed
      writeTo: function(bytes, thing, type, debug) {
    
    Jake Read's avatar
    Jake Read committed
        let phy = findPhy(type)
    
    Jake Read's avatar
    Jake Read committed
        // try some js type conversion,
        // course correction here: sometimes states that are numbers are saved as strings (json)
        // we can unf- this here,
        if (typeof thing === 'string' && isNumType(type)) {
    
    Jake Read's avatar
    Jake Read committed
          //console.warn('patching num')
    
    Jake Read's avatar
    Jake Read committed
          if (isIntType(type)) {
            thing = parseInt(thing)
          } else {
            thing = parseFloat(thing)
          }
    
    Jake Read's avatar
    Jake Read committed
          //console.log('new num val', thing)
    
    Jake Read's avatar
    Jake Read committed
        } else if (typeof thing === 'string' && type === 'boolean') {
          // ha! use (?) for 'truthiness'
    
    Jake Read's avatar
    Jake Read committed
          //console.warn('patching bool')
    
    Jake Read's avatar
    Jake Read committed
          if (thing == 'true') {
            thing = true
          } else {
            thing = false
          }
    
    Jake Read's avatar
    Jake Read committed
          //console.log('new bool val', thing)
    
    Jake Read's avatar
    Jake Read committed
        }
    
    Jake Read's avatar
    Jake Read committed
        let block = phy.write(thing)
    
        if (debug)
          console.log(`writing for type ${type} and thing '${thing}' the following block of bytes`, block)
          // write-in to msg like this
    
    Jake Read's avatar
    Jake Read committed
        // this *must be* slow AF, pls correct
    
    Jake Read's avatar
    Jake Read committed
        block.forEach((byte) => {
          bytes.push(byte)
        })
      },
    
    Jake Read's avatar
    Jake Read committed
      readFrom: function(bytes, place, type) {
    
    Jake Read's avatar
    Jake Read committed
        let phy = findPhy(type)
        // check that type exists at place, rip it oot and return it
    
    Jake Read's avatar
    Jake Read committed
        return phy.read(bytes, place)
    
    Jake Read's avatar
    Jake Read committed
      },
    
    Jake Read's avatar
    Jake Read committed
      readListFrom: function(bytes, place, type) {
    
    Jake Read's avatar
    Jake Read committed
        // using this where I expect a lit of values, i.e. the addLink(str,str,str,str) arguments,
        // plucks thru, continuing to pull values as long as the next in the serialized list is of
        // the right type
        let phy = findPhy(type)
        // the list of items,
        let list = new Array()
    
    Jake Read's avatar
    Jake Read committed
        while (place < bytes.length) {
    
    Jake Read's avatar
    Jake Read committed
          let res = phy.read(bytes, place)
          list.push(res.item)
          place += res.increment
    
          if (bytes[place] !== phy.key)
            break
            // this could throw us into infinite loops, so
          if (res.increment < 1)
            throw new Error('dangerous increment while reading list')
    
    Jake Read's avatar
    Jake Read committed
        }
    
        if (list.length < 1)
          throw new Error('reading list, found no items...')
        if (tsdebug)
          console.log('read list as', list)
    
    Jake Read's avatar
    Jake Read committed
        return list
      }
    }
    
    
    // typically: call, response expected
    // manager keys
    const MK = {
      // bzzt
    
    Jake Read's avatar
    Jake Read committed
      ERR: 254, // (str) message
    
      // heartbeats, wakeup
    
      HELLO: 231, // (eom)
    
      // request a top-level description
    
    Jake Read's avatar
    Jake Read committed
      QUERY: 251, // (eom)
    
    Jake Read's avatar
    Jake Read committed
      BRIEF: 250, // (str) name of interpreter, # hunks, # links (and then begin firing list back)
    
      // please show what is available
    
    Jake Read's avatar
    Jake Read committed
      REQLISTAVAIL: 249, // (eom)
      LISTOFAVAIL: 248, // (list)(str) names 'dirs/like/this' (includes programs ?) (this might be multiple packets?)
    
      // business ... we should be able to centralize all control w/i view.js if we can write these
    
    Jake Read's avatar
    Jake Read committed
      REQADDHUNK: 247, // (str) name
    
      REQNAMECHANGE: 246,
      HUNKALIVE: 245, // (hunkdescription): name, id, inputlist, outputlist, statelist
    
      HUNKREPLACE: 244,
      REQSTATECHANGE: 243,
      HUNKSTATECHANGE: 242,
      REQRMHUNK: 241, // (str) id
      HUNKREMOVED: 240, // (str) id
      REQADDLINK: 239, // (str) id, (str) outname, (str) id, (str) inname
      LINKALIVE: 238, // (str) id, (str) outname, (str) id, (str) inname
      REQRMLINK: 237, // (str) id, (str) outname, (str) id, (str) inname
      LINKREMOVED: 236, // (str) id, (str) outname, (str) id, (str) inname
    
    }
    
    // hunk description keys,
    const HK = {
      NAME: 253,
    
      INPUT: 249,
      OUTPUT: 247,
    
      CONNECTIONS: 246,
      CONNECTION: 245,
    
      STATE: 244
    
    Jake Read's avatar
    Jake Read committed
    
    
    Jake Read's avatar
    Jake Read committed
    // link keys,
    const LK = {
    
    Jake Read's avatar
    Jake Read committed
      ACK: 254,
      HELLO: 253 // ~ binary solo ~
    
    Jake Read's avatar
    Jake Read committed
    }
    
    
    Jake Read's avatar
    Jake Read committed
    // should write out as list of pairs ?
    // or write fn to do key(stringtype)
    
    
    Jake Read's avatar
    Jake Read committed
    export {
    
    Jake Read's avatar
    Jake Read committed
      TSET,
      MK, // manager keys
      HK, // hunk def keys
      LK, // link keys
    
    Jake Read's avatar
    Jake Read committed
      MSGS,
    
      isIntType,
      isFloatType,
      isNumType
    
    Jake Read's avatar
    Jake Read committed
    }