OverviewFilesCommitsIssuesDocsReleasesPeers

ollama_semantic_function_calling / ollamatools-new / keet / node_modules / bare-rpc / lib / messages.js

166 lines · javascript ref:
const c = require('compact-encoding')
const { type: t, stream: s } = require('./constants')
const errors = require('./errors')

const request = {
  preencode(state, m) {
    c.utf8.preencode(state, m.command)
    c.uint.preencode(state, m.stream)
    if (m.stream === 0) c.buffer.preencode(state, m.data)
  },
  encode(state, m) {
    c.utf8.encode(state, m.command)
    c.uint.encode(state, m.stream)
    if (m.stream === 0) c.buffer.encode(state, m.data)
  },
  decode(state, id) {
    const command = c.utf8.decode(state)
    const stream = c.uint.decode(state)
    const data = stream === 0 ? c.buffer.decode(state) : null

    return { type: t.REQUEST, id, command, stream, data }
  }
}

const error = {
  preencode(state, m) {
    c.utf8.preencode(state, m.message)
    c.utf8.preencode(state, m.code || '')
    c.int.preencode(state, m.errno || 0)
  },
  encode(state, m) {
    c.utf8.encode(state, m.message)
    c.utf8.encode(state, m.code || '')
    c.int.encode(state, m.errno || 0)
  },
  decode(state) {
    const err = new Error(`${c.utf8.decode(state)}`)
    err.code = c.utf8.decode(state)
    err.errno = c.int.decode(state)
    return err
  }
}

const response = {
  preencode(state, m) {
    c.bool.preencode(state, !!m.error)
    c.uint.preencode(state, m.stream)

    if (m.error) error.preencode(state, m.error)
    else if (m.stream === 0) c.buffer.preencode(state, m.data)
  },
  encode(state, m) {
    c.bool.encode(state, !!m.error)
    c.uint.encode(state, m.stream)

    if (m.error) error.encode(state, m)
    else if (m.stream === 0) c.buffer.encode(state, m.data)
  },
  decode(state) {
    const error = c.bool.decode(state)
    const stream = c.uint.decode(state)

    if (error) return { stream, error: error.decode(state), data: null }
    if (stream === 0)
      return { stream, error: null, data: c.buffer.decode(state) }

    return { stream, error: null, data: null }
  }
}

const stream = {
  preencode(state, m) {
    c.uint.preencode(state, m.stream)

    if (m.stream & s.ERROR) error.preencode(state, m.error)
    else if (m.stream & s.DATA) c.buffer.preencode(state, m.data)
  },
  encode(state, m) {
    c.uint.encode(state, m.stream)

    if (m.stream & s.ERROR) error.encode(state, m.error)
    else if (m.stream & s.DATA) c.buffer.encode(state, m.data)
  },
  decode(state) {
    const stream = c.uint.decode(state)

    if (stream & s.ERROR)
      return { stream, error: error.decode(state), data: null }
    if (stream & s.DATA)
      return { stream, error: null, data: c.buffer.decode(state) }

    return { stream, error: null, data: null }
  }
}

exports.message = {
  preencode(state, m) {
    c.uint32.preencode(state, 0) // Frame
    c.uint.preencode(state, m.type)
    c.uint.preencode(state, m.id)

    switch (m.type) {
      case t.REQUEST:
        request.preencode(state, m)
        break
      case t.RESPONSE:
        response.preencode(state, m)
        break
      case t.STREAM:
        stream.preencode(state, m)
        break
    }
  },
  encode(state, m) {
    const frame = state.start

    c.uint32.encode(state, 0) // Frame

    const start = state.start

    c.uint.encode(state, m.type)
    c.uint.encode(state, m.id)

    switch (m.type) {
      case t.REQUEST:
        request.encode(state, m)
        break
      case t.RESPONSE:
        response.encode(state, m)
        break
      case t.STREAM:
        stream.encode(state, m)
        break
    }

    const end = state.start

    state.start = frame

    c.uint32.encode(state, end - start)

    state.start = end
  },
  decode(state) {
    if (state.end - state.start < 4) return null

    const frame = c.uint32.decode(state)

    if (state.end - state.start < frame) return null

    const type = c.uint.decode(state)
    const id = c.uint.decode(state)

    switch (type) {
      case t.REQUEST:
        return { type, id, ...request.decode(state, id) }
      case t.RESPONSE:
        return { type, id, ...response.decode(state, id) }
      case t.STREAM:
        return { type, id, ...stream.decode(state, id) }
      default:
        throw errors.UNKNOWN_MESSAGE(`Unknown message '${type}'`)
    }
  }
}