@helia/bitswap
Version:
JavaScript implementation of the Bitswap data exchange protocol used by Helia
471 lines (392 loc) • 12 kB
text/typescript
/* eslint-disable import/export */
/* eslint-disable complexity */
/* eslint-disable @typescript-eslint/no-namespace */
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
/* eslint-disable @typescript-eslint/no-empty-interface */
import { type Codec, CodeError, decodeMessage, type DecodeOptions, encodeMessage, enumeration, message } from 'protons-runtime'
import { alloc as uint8ArrayAlloc } from 'uint8arrays/alloc'
import type { Uint8ArrayList } from 'uint8arraylist'
export enum WantType {
WantBlock = 'WantBlock',
WantHave = 'WantHave'
}
enum __WantTypeValues {
WantBlock = 0,
WantHave = 1
}
export namespace WantType {
export const codec = (): Codec<WantType> => {
return enumeration<WantType>(__WantTypeValues)
}
}
export interface WantlistEntry {
cid: Uint8Array
priority: number
cancel?: boolean
wantType?: WantType
sendDontHave?: boolean
}
export namespace WantlistEntry {
let _codec: Codec<WantlistEntry>
export const codec = (): Codec<WantlistEntry> => {
if (_codec == null) {
_codec = message<WantlistEntry>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if ((obj.cid != null && obj.cid.byteLength > 0)) {
w.uint32(10)
w.bytes(obj.cid)
}
if ((obj.priority != null && obj.priority !== 0)) {
w.uint32(16)
w.int32(obj.priority)
}
if (obj.cancel != null) {
w.uint32(24)
w.bool(obj.cancel)
}
if (obj.wantType != null) {
w.uint32(32)
WantType.codec().encode(obj.wantType, w)
}
if (obj.sendDontHave != null) {
w.uint32(40)
w.bool(obj.sendDontHave)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length, opts = {}) => {
const obj: any = {
cid: uint8ArrayAlloc(0),
priority: 0
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
obj.cid = reader.bytes()
break
}
case 2: {
obj.priority = reader.int32()
break
}
case 3: {
obj.cancel = reader.bool()
break
}
case 4: {
obj.wantType = WantType.codec().decode(reader)
break
}
case 5: {
obj.sendDontHave = reader.bool()
break
}
default: {
reader.skipType(tag & 7)
break
}
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<WantlistEntry>): Uint8Array => {
return encodeMessage(obj, WantlistEntry.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<WantlistEntry>): WantlistEntry => {
return decodeMessage(buf, WantlistEntry.codec(), opts)
}
}
export interface Wantlist {
entries: WantlistEntry[]
full?: boolean
}
export namespace Wantlist {
let _codec: Codec<Wantlist>
export const codec = (): Codec<Wantlist> => {
if (_codec == null) {
_codec = message<Wantlist>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if (obj.entries != null) {
for (const value of obj.entries) {
w.uint32(10)
WantlistEntry.codec().encode(value, w)
}
}
if (obj.full != null) {
w.uint32(16)
w.bool(obj.full)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length, opts = {}) => {
const obj: any = {
entries: []
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
if (opts.limits?.entries != null && obj.entries.length === opts.limits.entries) {
throw new CodeError('decode error - map field "entries" had too many elements', 'ERR_MAX_LENGTH')
}
obj.entries.push(WantlistEntry.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.entries$
}))
break
}
case 2: {
obj.full = reader.bool()
break
}
default: {
reader.skipType(tag & 7)
break
}
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<Wantlist>): Uint8Array => {
return encodeMessage(obj, Wantlist.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<Wantlist>): Wantlist => {
return decodeMessage(buf, Wantlist.codec(), opts)
}
}
export interface Block {
prefix: Uint8Array
data: Uint8Array
}
export namespace Block {
let _codec: Codec<Block>
export const codec = (): Codec<Block> => {
if (_codec == null) {
_codec = message<Block>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if ((obj.prefix != null && obj.prefix.byteLength > 0)) {
w.uint32(10)
w.bytes(obj.prefix)
}
if ((obj.data != null && obj.data.byteLength > 0)) {
w.uint32(18)
w.bytes(obj.data)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length, opts = {}) => {
const obj: any = {
prefix: uint8ArrayAlloc(0),
data: uint8ArrayAlloc(0)
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
obj.prefix = reader.bytes()
break
}
case 2: {
obj.data = reader.bytes()
break
}
default: {
reader.skipType(tag & 7)
break
}
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<Block>): Uint8Array => {
return encodeMessage(obj, Block.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<Block>): Block => {
return decodeMessage(buf, Block.codec(), opts)
}
}
export enum BlockPresenceType {
HaveBlock = 'HaveBlock',
DontHaveBlock = 'DontHaveBlock'
}
enum __BlockPresenceTypeValues {
HaveBlock = 0,
DontHaveBlock = 1
}
export namespace BlockPresenceType {
export const codec = (): Codec<BlockPresenceType> => {
return enumeration<BlockPresenceType>(__BlockPresenceTypeValues)
}
}
export interface BlockPresence {
cid: Uint8Array
type: BlockPresenceType
}
export namespace BlockPresence {
let _codec: Codec<BlockPresence>
export const codec = (): Codec<BlockPresence> => {
if (_codec == null) {
_codec = message<BlockPresence>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if ((obj.cid != null && obj.cid.byteLength > 0)) {
w.uint32(10)
w.bytes(obj.cid)
}
if (obj.type != null && __BlockPresenceTypeValues[obj.type] !== 0) {
w.uint32(16)
BlockPresenceType.codec().encode(obj.type, w)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length, opts = {}) => {
const obj: any = {
cid: uint8ArrayAlloc(0),
type: BlockPresenceType.HaveBlock
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
obj.cid = reader.bytes()
break
}
case 2: {
obj.type = BlockPresenceType.codec().decode(reader)
break
}
default: {
reader.skipType(tag & 7)
break
}
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<BlockPresence>): Uint8Array => {
return encodeMessage(obj, BlockPresence.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<BlockPresence>): BlockPresence => {
return decodeMessage(buf, BlockPresence.codec(), opts)
}
}
export interface BitswapMessage {
wantlist?: Wantlist
blocks: Block[]
blockPresences: BlockPresence[]
pendingBytes: number
}
export namespace BitswapMessage {
let _codec: Codec<BitswapMessage>
export const codec = (): Codec<BitswapMessage> => {
if (_codec == null) {
_codec = message<BitswapMessage>((obj, w, opts = {}) => {
if (opts.lengthDelimited !== false) {
w.fork()
}
if (obj.wantlist != null) {
w.uint32(10)
Wantlist.codec().encode(obj.wantlist, w)
}
if (obj.blocks != null) {
for (const value of obj.blocks) {
w.uint32(26)
Block.codec().encode(value, w)
}
}
if (obj.blockPresences != null) {
for (const value of obj.blockPresences) {
w.uint32(34)
BlockPresence.codec().encode(value, w)
}
}
if ((obj.pendingBytes != null && obj.pendingBytes !== 0)) {
w.uint32(40)
w.int32(obj.pendingBytes)
}
if (opts.lengthDelimited !== false) {
w.ldelim()
}
}, (reader, length, opts = {}) => {
const obj: any = {
blocks: [],
blockPresences: [],
pendingBytes: 0
}
const end = length == null ? reader.len : reader.pos + length
while (reader.pos < end) {
const tag = reader.uint32()
switch (tag >>> 3) {
case 1: {
obj.wantlist = Wantlist.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.wantlist
})
break
}
case 3: {
if (opts.limits?.blocks != null && obj.blocks.length === opts.limits.blocks) {
throw new CodeError('decode error - map field "blocks" had too many elements', 'ERR_MAX_LENGTH')
}
obj.blocks.push(Block.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.blocks$
}))
break
}
case 4: {
if (opts.limits?.blockPresences != null && obj.blockPresences.length === opts.limits.blockPresences) {
throw new CodeError('decode error - map field "blockPresences" had too many elements', 'ERR_MAX_LENGTH')
}
obj.blockPresences.push(BlockPresence.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.blockPresences$
}))
break
}
case 5: {
obj.pendingBytes = reader.int32()
break
}
default: {
reader.skipType(tag & 7)
break
}
}
}
return obj
})
}
return _codec
}
export const encode = (obj: Partial<BitswapMessage>): Uint8Array => {
return encodeMessage(obj, BitswapMessage.codec())
}
export const decode = (buf: Uint8Array | Uint8ArrayList, opts?: DecodeOptions<BitswapMessage>): BitswapMessage => {
return decodeMessage(buf, BitswapMessage.codec(), opts)
}
}