Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

WIP: Adding JSDoc supporrted types #3046

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions packages/ipfs-core-utils/src/files/normalise-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const errCode = require('err-code')
const { Buffer } = require('buffer')
const globalThis = require('ipfs-utils/src/globalthis')

/*
/**
* Transform one of:
*
* ```
Expand Down Expand Up @@ -43,8 +43,17 @@ const globalThis = require('ipfs-utils/src/globalthis')
* AsyncIterable<{ path, content: AsyncIterable<Buffer> }>
* ```
*
* @param input Object
* @return AsyncInterable<{ path, content: AsyncIterable<Buffer> }>
* @typedef {Buffer|ArrayBuffer|ArrayBufferView} Bytes
* @typedef {Object} FileInput
* @property {string} path
* @property {FileContent} content
* @typedef {ReadableStream|Iterable<number>|Iterable<ArrayBuffer>|Iterable<ArrayBufferView>|AsyncIterator<ArrayBuffer>|AsyncIterable<ArrayBufferView>} ChunkedContent
* @typedef {string|String|ArrayBuffer|ArrayBufferView|Blob|ChunkedContent} FileContent
* @typedef {FileContent|FileInput} Input
*
*
* @param {Input} input
* @returns {AsyncIterable<FileObject>}
*/
module.exports = function normaliseInput (input) {
// must give us something
Expand Down Expand Up @@ -151,6 +160,22 @@ module.exports = function normaliseInput (input) {
throw errCode(new Error('Unexpected input: ' + typeof input), 'ERR_UNEXPECTED_INPUT')
}

/**
* @typedef {Object} Time
* @property {number} secs
* @property {number} nsecs
*
*
* @typedef {Object} FileObject
* @property {string} path
* @property {mode} [number]
* @property {Time|Date|[number]|[number,number]} mtime
* @property {AsyncIterable<Buffer>} content
*
* @param {*} input
* @returns {FileObject}
*/

function toFileObject (input) {
const obj = {
path: input.path || '',
Expand Down
26 changes: 26 additions & 0 deletions packages/ipfs/src/core/api-manager.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
'use strict'

/**
* @template T
* @typedef {import("ipfs-interface").Values<T>} Values
*/

/**
* @template U
* @typedef {import("ipfs-interface").UnionToIntersection<U>} UnionToIntersection
*/

/**
* @template T
* @typedef {Object} APIUpdate
* @property {UnionToIntersection<Values<T>>} api
* @property {function():void} cancel
*/

module.exports = class ApiManager {
constructor () {
/** @type {Record<string, any>} */
this._api = {}
this._onUndef = () => undefined
/** @type {any} */
this.api = new Proxy(this._api, {
get: (_, prop) => {
if (prop === 'then') return undefined // Not a promise!
// @ts-ignore
return this._api[prop] === undefined ? this._onUndef(prop) : this._api[prop]
}
})
}

/**
* @template T
* @param {T} nextApi
* @param {function(): any} [onUndef]
* @returns {APIUpdate<T>}
*/
update (nextApi, onUndef) {
const prevApi = { ...this._api }
const prevUndef = this._onUndef
Expand Down
111 changes: 105 additions & 6 deletions packages/ipfs/src/core/components/add/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,64 @@ const { parseChunkerString } = require('./utils')
const pipe = require('it-pipe')
const { withTimeoutOption } = require('../../utils')

/**
* @typedef {import('ipfs-interface').CID} CID
* @typedef {import('ipfs-core-utils/src/files/normalise-input').Input} AddInput
* @typedef {import('../init').PreloadService} PreloadService
* @typedef {import('../init').Pin} Pin
* @typedef {import('../init').GCLock} GCLock
* @typedef {import('../init').Block} Block
* @typedef {import('../init').ConstructorOptions} ConstructorOptions
*/
/**
* @typedef {Object} AddOutput
* @property {string} path
* @property {CID} cid
* @property {number} size
* @property {Mode} mode
* @property {Time} mtime
*
* @typedef {string} Mode
* @typedef {Object} Time
* @property {number} secs
* @property {number} nsecs
*
* @param {Object} config
* @param {Block} config.block
* @param {GCLock} config.gcLock
* @param {PreloadService} config.preload
* @param {Pin} config.pin
* @param {ConstructorOptions} config.options
* @returns {Add}
*/
module.exports = ({ block, gcLock, preload, pin, options: constructorOptions }) => {
const isShardingEnabled = constructorOptions.EXPERIMENTAL && constructorOptions.EXPERIMENTAL.sharding

return withTimeoutOption(async function * add (source, options) {
/**
* @typedef {Object} AddOptions
* @property {string} [chunker="size-262144"]
* @property {number} [cidVersion=0]
* @property {boolean} [enableShardingExperiment]
* @property {string} [hashAlg="sha2-256"]
* @property {boolean} [onlyHash=false]
* @property {boolean} [pin=true]
* @property {function(number):void} [progress]
* @property {boolean} [rawLeaves=false]
* @property {number} [shardSplitThreshold=1000]
* @property {boolean} [trickle=false]
* @property {boolean} [wrapWithDirectory=false]
*
* @callback Add
* @param {AddInput} source
* @param {AddOptions} [options]
* @returns {AsyncIterable<AddOutput>}
*
* @type {Add}
*/
async function * add (source, options) {
options = options || {}

/** @type {AddOptions & {shardSplitThreshold:number, strategy:'balanced'|'trickle', chunker:'fixed'|'rabin'}} */
// @ts-ignore - chunker field of AddOptions and this are incompatible
const opts = {
shardSplitThreshold: isShardingEnabled ? 1000 : Infinity,
...options,
Expand Down Expand Up @@ -58,11 +110,25 @@ module.exports = ({ block, gcLock, preload, pin, options: constructorOptions })
} finally {
releaseLock()
}
})
}

return withTimeoutOption(add)
}

/**
* @param {Object} opts
* @param {number} [opts.cidVersion]
* @param {boolean} [opts.wrapWithDirectory]
* @returns {TransformFile}
*/
function transformFile (opts) {
return async function * (source) {
/**
* @callback TransformFile
* @param {AsyncIterable<?>} source
* @returns {AsyncIterable<AddOutput>}
* @type {TransformFile}
*/
async function * transformFile (source) {
for await (const file of source) {
let cid = file.cid

Expand All @@ -85,10 +151,26 @@ function transformFile (opts) {
}
}
}

return transformFile
}

/**
* @param {PreloadService} preload
* @param {Object} opts
* @param {boolean} [opts.wrapWithDirectory]
* @param {boolean} [opts.onlyHash]
* @param {boolean} [opts.preload]
* @returns {Preloader}
*/
function preloadFile (preload, opts) {
return async function * (source) {
/**
* @callback Preloader
* @param {AsyncIterable<AddOutput>} source
* @returns {AsyncIterable<AddOutput>}
* @type {Preloader}
*/
async function * preloader (source) {
for await (const file of source) {
const isRootFile = !file.path || opts.wrapWithDirectory
? file.path === ''
Expand All @@ -103,10 +185,25 @@ function preloadFile (preload, opts) {
yield file
}
}

return preloader
}

/**
* @param {Pin} pin
* @param {Object} opts
* @param {boolean} [opts.pin]
* @param {boolean} [opts.onlyHash]
* @returns {Pinner}
*/
function pinFile (pin, opts) {
return async function * (source) {
/**
* @callback Pinner
* @param {AsyncIterable<AddOutput>} source
* @returns {AsyncIterable<AddOutput>}
* @type {Pinner}
*/
async function * pinner (source) {
for await (const file of source) {
// Pin a file if it is the root dir of a recursive add or the single file
// of a direct add.
Expand All @@ -125,4 +222,6 @@ function pinFile (pin, opts) {
yield file
}
}

return pinner
}
5 changes: 5 additions & 0 deletions packages/ipfs/src/core/components/add/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ const parseRabinString = (chunker) => {
return options
}

/**
* @param {string} str
* @param {string} name
* @returns {number}
*/
const parseChunkSize = (str, name) => {
const size = parseInt(str)
if (isNaN(size)) {
Expand Down
37 changes: 34 additions & 3 deletions packages/ipfs/src/core/components/bitswap/stat.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
'use strict'

const Big = require('bignumber.js')
const { BigNumber: Big } = require('bignumber.js')
const CID = require('cids')
const { withTimeoutOption } = require('../../utils')

/**
* @typedef {import('ipfs-bitswap')} BitSwap
*/

/**
* @typedef {Object} StatConfig
* @property {BitSwap} bitswap
*
* @typedef {Object} BitswapStat
* @property {number} provideBufLen
* @property {CID[]} wantlist
* @property {string[]} peers
* @property {Big} blocksReceived
* @property {Big} dataReceived
* @property {Big} blocksSent
* @property {Big} dataSent
* @property {Big} dupBlksReceived
* @property {Big} dupDataReceived
*
* @param {StatConfig} config
* @returns {Stat}
*/
module.exports = ({ bitswap }) => {
return withTimeoutOption(async function stat () { // eslint-disable-line require-await
/**
* @callback Stat
* @returns {Promise<BitswapStat>}
*/
async function stat () { // eslint-disable-line require-await
// @ts-ignore
const snapshot = bitswap.stat().snapshot

return {
provideBufLen: parseInt(snapshot.providesBufferLength.toString()),
blocksReceived: new Big(snapshot.blocksReceived),
// @ts-ignore
wantlist: Array.from(bitswap.getWantlist()).map(e => e[1].cid),
// @ts-ignore
peers: bitswap.peers().map(id => new CID(id.toB58String())),
dupBlksReceived: new Big(snapshot.dupBlksReceived),
dupDataReceived: new Big(snapshot.dupDataReceived),
dataReceived: new Big(snapshot.dataReceived),
blocksSent: new Big(snapshot.blocksSent),
dataSent: new Big(snapshot.dataSent)
}
})
}

return withTimeoutOption(stat)
}
27 changes: 25 additions & 2 deletions packages/ipfs/src/core/components/bitswap/unwant.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,28 @@ const CID = require('cids')
const errCode = require('err-code')
const { withTimeoutOption } = require('../../utils')

/**
* @typedef {import('ipfs-bitswap')} BitSwap
* @typedef {import('../../utils').WithTimeoutOptions} WithTimeoutOptions
*/

/**
* @typedef {Object} Config
* @property {BitSwap} bitswap
*
* @param {Config} config
* @returns {Unwant}
*/
module.exports = ({ bitswap }) => {
return withTimeoutOption(async function unwant (keys, options) { // eslint-disable-line require-await
/**
* @callback Unwant
* @param {CID[]|CID} keys
* @param {WithTimeoutOptions} [options]
* @returns {Promise<void>}
*
* @type {Unwant}
*/
async function unwant (keys, options) { // eslint-disable-line require-await
if (!Array.isArray(keys)) {
keys = [keys]
}
Expand All @@ -16,6 +36,9 @@ module.exports = ({ bitswap }) => {
throw errCode(err, 'ERR_INVALID_CID')
}

// @ts-ignore - ipfs-bitswap does not expect options
return bitswap.unwant(keys, options)
})
}

return withTimeoutOption(unwant)
}
Loading