Skip to content
This repository has been 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 4 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').PinService} PinService
* @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 {PinService} 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 {PinService} 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
}
44 changes: 42 additions & 2 deletions packages/ipfs/src/core/components/block/put.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,44 @@ const CID = require('cids')
const isIPFS = require('is-ipfs')
const { withTimeoutOption } = require('../../utils')

/**
* @typedef {import("ipfs-interface").BlockService} BlockService
* @typedef {import("ipfs-interface").GCLock} GCLock
* @typedef {import("ipfs-interface").PreloadService} PreloadService
* @typedef {import("ipfs-interface").PinService} PinService
*/

/**
* @typedef {Object} PutConfig
* @property {BlockService} blockService
* @property {GCLock} gcLock
* @property {PreloadService} preload
* @property {PinService} pin
*
* @param {PutConfig} config
* @returns {Put}
*/
module.exports = ({ blockService, pin, gcLock, preload }) => {
return withTimeoutOption(async function put (block, options) {
/**
* @typedef {Object} PutOptions
* @property {CID} [cid]
* @property {string} [format="dag-pb"]
* @property {string} [mhtype="sha2-256"]
* @property {number} [mhlen]
* @property {0|1} [version=0]
* @property {boolean} [pin=false]
* @property {number} [timeout]
* @property {boolean} [preload]
* @property {AbortSignal} [signal]
*
* @callback Put
* @param {Block|Buffer} block
* @param {PutOptions} [options]
* @returns {Promise<Block>}
*
* @type {Put}
*/
async function put (block, options) {
options = options || {}

if (Array.isArray(block)) {
Expand All @@ -20,6 +56,7 @@ module.exports = ({ blockService, pin, gcLock, preload }) => {
} else {
const mhtype = options.mhtype || 'sha2-256'
const format = options.format || 'dag-pb'
/** @type {0|1} */
let cidVersion

if (options.version == null) {
Expand All @@ -39,6 +76,7 @@ module.exports = ({ blockService, pin, gcLock, preload }) => {
const release = await gcLock.readLock()

try {
// @ts-ignore - blockService.put doesn't take second arg yet.
await blockService.put(block, {
signal: options.signal
})
Expand All @@ -58,5 +96,7 @@ module.exports = ({ blockService, pin, gcLock, preload }) => {
} finally {
release()
}
})
}

return withTimeoutOption(put)
}
Loading