UNPKG

ipfs-bitswap

Version:

JavaScript implementation of the Bitswap data exchange protocol used by IPFS

109 lines (91 loc) 2.68 kB
import { logger as createLogger, type Logger } from '@libp2p/logger' import { equals as uint8ArrayEquals } from 'uint8arrays/equals' import { BitswapMessageEntry } from '../message/entry.js' import type { PeerId } from '@libp2p/interface' /** * Creates a logger for the given subsystem */ export const logger = (id: PeerId, subsystem?: string): Logger => { const name = ['bitswap'] if (subsystem != null) { name.push(subsystem) } if (id != null) { name.push(`${id.toString().slice(0, 8)}`) } return createLogger(name.join(':')) } export const includesWith = <X, T> (pred: (x: X, t: T) => boolean, x: X, list: T[]): boolean => { let idx = 0 const len = list.length while (idx < len) { if (pred(x, list[idx])) { return true } idx += 1 } return false } export const uniqWith = <T> (pred: (x: T, t: T) => boolean, list: T[]): T[] => { let idx = 0 const len = list.length const result = [] let item while (idx < len) { item = list[idx] if (!includesWith(pred, item, result)) { result[result.length] = item } idx += 1 } return result } export const groupBy = <K extends string | number | symbol, V> (pred: (v: V) => K, list: V[]): Record<K, V[]> => { // @ts-expect-error cannot use {} as record with these key types? const output: Record<K, V[]> = {} return list.reduce((acc, v) => { const k = pred(v) if (acc[k] != null) { acc[k].push(v) } else { acc[k] = [v] } return acc }, output) } export const pullAllWith = <T, E> (pred: (a: T, b: E) => boolean, list: T[], values: E[]): T[] => { return list.filter(i => { return !includesWith(pred, i, values) }) } export const sortBy = <T> (fn: (v: T) => number, list: T[]): T[] => { return Array.prototype.slice.call(list, 0).sort((a, b) => { const aa = fn(a) const bb = fn(b) return aa < bb ? -1 : aa > bb ? 1 : 0 }) } /** * Is equal for Maps of BitswapMessageEntry or Uint8Arrays */ export const isMapEqual = (a: Map<string, Uint8Array | BitswapMessageEntry>, b: Map<string, Uint8Array | BitswapMessageEntry>): boolean => { if (a.size !== b.size) { return false } for (const [key, valueA] of a) { const valueB = b.get(key) if (valueB === undefined) { return false } // TODO: revisit this // Support Blocks if (valueA instanceof Uint8Array && valueB instanceof Uint8Array && !uint8ArrayEquals(valueA, valueB)) { return false } // Support BitswapMessageEntry if (valueA instanceof BitswapMessageEntry && valueB instanceof BitswapMessageEntry && !valueA.equals(valueB)) { return false } } return true }