Skip to content

Commit

Permalink
feat: add types (#651)
Browse files Browse the repository at this point in the history
Adds typescript support for this module.

BREAKING CHANGE: things are now typed which may be suprising
  • Loading branch information
achingbrain authored Jul 30, 2021
1 parent 1b4b936 commit 0f30547
Show file tree
Hide file tree
Showing 22 changed files with 429 additions and 207 deletions.
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
- run: npm run lint
- run: npm run build
- run: npx aegir dep-check
- uses: gozala/[email protected]
#- uses: ipfs/aegir/actions/bundle-size@master
# name: size
# with:
Expand Down
21 changes: 10 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"jsdelivr": "dist/index.min.js",
"unpkg": "dist/index.min.js",
"scripts": {
"lint": "aegir lint",
"lint": "aegir ts -p check && aegir lint",
"docs": "aegir docs",
"build": "aegir build",
"test": "aegir test",
Expand Down Expand Up @@ -42,8 +42,7 @@
"@hapi/hapi": "^20.0.0",
"debug": "^4.1.1",
"execa": "^5.0.0",
"fs-extra": "^9.0.0",
"ipfs-utils": "^7.0.0",
"ipfs-utils": "^8.1.4",
"joi": "^17.2.1",
"merge-options": "^3.0.1",
"multiaddr": "^10.0.0",
Expand All @@ -52,14 +51,14 @@
"temp-write": "^4.0.0"
},
"devDependencies": {
"aegir": "^33.0.0",
"assert": "^2.0.0",
"benchmark": "^2.1.4",
"go-ipfs": "^0.8.0",
"ipfs": "next",
"ipfs-client": "next",
"ipfs-http-client": "next",
"ipfs-unixfs": "^4.0.1"
"@types/hapi__hapi": "^20.0.9",
"aegir": "^34.1.0",
"go-ipfs": "^0.9.1",
"ipfs": "^0.56.1",
"ipfs-client": "^0.5.1",
"ipfs-http-client": "^51.0.1",
"ipfs-unixfs": "^5.0.0",
"util": "^0.12.4"
},
"repository": {
"type": "git",
Expand Down
5 changes: 5 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

const { isBrowser, isWebWorker } = require('ipfs-utils/src/env')

/**
* @param {object} args
* @param {import('./types').NodeType} args.type
*/
module.exports = ({ type }) => {
/** @type {string[]} */
let swarm

// from the browser tell remote nodes to listen over WS
Expand Down
9 changes: 8 additions & 1 deletion src/endpoint/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const routeOptions = {
})
}
}

/**
* @param {Error & { stdout?: string }} err
*/
const badRequest = err => {
let msg
if (err.stdout) {
Expand All @@ -24,12 +28,15 @@ const badRequest = err => {
throw boom.badRequest(msg)
}

/**
* @type {Record<string, any>}
*/
const nodes = {}

/**
* @namespace EndpointServerRoutes
* @ignore
* @param {Hapi.Server} server
* @param {import('@hapi/hapi').Server} server
* @param {Function} createFactory
* @returns {void}
*/
Expand Down
12 changes: 6 additions & 6 deletions src/endpoint/server.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ class Server {
/**
* Start the server
*
* @returns {Promise<Hapi.Server>}
* @returns {Promise<Server>}
*/
start () {
async start () {
console.warn('Server not implemented in the browser')
return Promise.resolve(this)

return this
}

/**
* Stop the server
*
* @returns {Promise}
* @returns {Promise<void>}
*/
stop () {
async stop () {
console.warn('Server not implemented in the browser')
return Promise.resolve(this)
}
}

Expand Down
23 changes: 14 additions & 9 deletions src/endpoint/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,23 @@ class Server {
/**
* @class
* @param {Object} options
* @param {number} [options.port=43134] - Server port.
* @param {number} [options.port=43134]
* @param {string} [options.host='localhost']
* @param {Function} createFactory
*/
constructor (options = { port: 43134, host: 'localhost' }, createFactory) {
this.options = options
this.server = null
this.port = this.options.port
this.host = this.options.host
this.port = this.options.port == null ? 43134 : this.options.port
this.host = this.options.host == null ? 'localhost' : this.options.host
this.createFactory = createFactory
}

/**
* Start the server
*
* @param {number} port
* @returns {Promise<Hapi.Server>}
* @returns {Promise<Server>}
*/
async start (port = this.port) {
this.port = port
Expand All @@ -42,17 +43,21 @@ class Server {
routes(this.server, this.createFactory)

await this.server.start()
return this.server

return this
}

/**
* Stop the server
*
* @param {object} [options] - {@link https://hapi.dev/api/?v=18.4.0#-await-serverstopoptions Hapi docs}
* @returns {Promise}
* @param {object} [options]
* @param {number} options.timeout
* @returns {Promise<void>}
*/
stop (options) {
return this.server.stop(options)
async stop (options) {
if (this.server) {
await this.server.stop(options)
}
}
}

Expand Down
37 changes: 20 additions & 17 deletions src/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ const ControllerRemote = require('./ipfsd-client')
const ControllerProc = require('./ipfsd-in-proc')
const testsConfig = require('./config')

/** @typedef {import("./index").ControllerOptions} ControllerOptions */
/** @typedef {import("./index").ControllerOptionsOverrides} ControllerOptionsOverrides */
/** @typedef {import("./index").IpfsOptions} IpfsOptions */
/**
* @typedef {import("./types").ControllerOptions} ControllerOptions
* @typedef {import("./types").ControllerOptionsOverrides} ControllerOptionsOverrides
* @typedef {import("./types").IPFSOptions} IPFSOptions
* @typedef {import('./types').Controller} Controller
*/

const defaults = {
remote: !isNode,
Expand Down Expand Up @@ -45,7 +48,7 @@ class Factory {
proc: merge(this.opts, { type: 'proc' })
}, overrides)

/** @type ControllerDaemon[] */
/** @type {Controller[]} */
this.controllers = []
}

Expand All @@ -54,25 +57,28 @@ class Factory {
* useful in browsers to be able to generate temp
* repos manually
*
* @param {ControllerOptions} options - Controller type
*
* @param {ControllerOptions} [options]
* @returns {Promise<string>}
*/
async tmpDir (options) {
options = merge(this.opts, options)
if (options.remote) {
async tmpDir (options = {}) {
const opts = merge(this.opts, options)

if (opts.remote) {
const res = await http.get(
`${options.endpoint}/util/tmp-dir`,
{ searchParams: { type: options.type } }
`${opts.endpoint}/util/tmp-dir`,
{ searchParams: new URLSearchParams({ type: `${opts.type}` }) }
)
const out = await res.json()

return out.tmpDir
}

return Promise.resolve(tmpDir(options.type))
return Promise.resolve(tmpDir(opts.type))
}

/**
* @param {IPFSOptions & { endpoint: string }} options
*/
async _spawnRemote (options) {
const opts = {
json: {
Expand Down Expand Up @@ -100,10 +106,10 @@ class Factory {
* Spawn an IPFSd Controller
*
* @param {ControllerOptions} options
* @returns {Promise<ControllerDaemon>}
* @returns {Promise<ControllerDaemon | ControllerProc | ControllerRemote>}
*/
async spawn (options = { }) {
const type = options.type || this.opts.type
const type = options.type || this.opts.type || 'go'
const opts = merge(
this.overrides[type],
options
Expand Down Expand Up @@ -152,13 +158,10 @@ class Factory {

/**
* Stop all controllers
*
* @returns {Promise<ControllerDaemon[]>}
*/
async clean () {
await Promise.all(this.controllers.map(n => n.stop()))
this.controllers = []
return this
}
}

Expand Down
64 changes: 10 additions & 54 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
const Factory = require('./factory')
const Server = require('./endpoint/server')

/** @typedef {import("./ipfsd-daemon")} Controller */
/**
* @typedef {import("./types").Controller} Controller
* @typedef {import("./types").ControllerOptions} ControllerOptions
* @typedef {import("./types").ControllerOptionsOverrides} ControllerOptionsOverrides
*/

/**
* Creates a factory
*
* @param {ControllerOptions} options
* @param {ControllerOptionsOverrides} overrides
* @param {ControllerOptions} [options]
* @param {ControllerOptionsOverrides} [overrides]
* @returns {Factory}
*/
const createFactory = (options, overrides) => {
Expand All @@ -30,11 +34,9 @@ const createController = (options) => {
/**
* Create a Endpoint Server
*
* @param {(Object|number)} options - Configuration options or just the port.
* @param {number} options.port - Port to start the server on.
* @param {ControllerOptions} factoryOptions
* @param {ControllerOptionsOverrides} factoryOverrides
* @returns {Server}
* @param {number | { port: number }} [options] - Configuration options or just the port.
* @param {ControllerOptions} [factoryOptions]
* @param {ControllerOptionsOverrides} [factoryOverrides]
*/
const createServer = (options, factoryOptions = {}, factoryOverrides = {}) => {
if (typeof options === 'number') {
Expand All @@ -51,49 +53,3 @@ module.exports = {
createController,
createServer
}

/**
* Same as https://github.com/ipfs/js-ipfs/blob/master/README.md#ipfs-constructor
*
* @typedef {Object} IpfsOptions
* @property {string|Object} [repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an ipfs.Repo instance.
* @property {boolean|Object} [init=true] - Initialize the repo when creating the IPFS node. Instead of a boolean, you may provide an object with custom initialization options. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsinit
* @property {boolean} [start=true] - If false, do not automatically start the IPFS node. Instead, you’ll need to manually call node.start() yourself.
* @property {string} [pass=null] - A passphrase to encrypt/decrypt your keys.
* @property {boolean} [silent=false] - Prevents all logging output from the IPFS node.
* @property {object} [relay] - Configure circuit relay. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsrelay Default: `{ enabled: true, hop: { enabled: false, active: false } }`
* @property {object} [preload] - Configure remote preload nodes. The remote will preload content added on this node, and also attempt to preload objects requested by this node. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionspreload Default: `{ enabled: true, addresses: [...]`
* @property {object} [EXPERIMENTAL] - Enable and configure experimental features. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsexperimental Default: `{ ipnsPubsub: false, sharding: false }`
* @property {object} [config] - Modify the default IPFS node config. This object will be merged with the default config; it will not replace it. The default config is documented in the js-ipfs config file docs. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsconfig
* @property {object} [ipld] - Modify the default IPLD config. This object will be merged with the default config; it will not replace it. Check IPLD docs for more information on the available options. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsipld
* @property {object | Function} [libp2p] - The libp2p option allows you to build your libp2p node by configuration, or via a bundle function. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionslibp2p
* @property {object} [connectionManager] - Configure the libp2p connection manager. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsconnectionmanager
* @property {boolean} [offline=false] - Run the node offline.
*/

/**
* @typedef {Object} ControllerOptions
* @property {boolean} [test=false] - Flag to activate custom config for tests.
* @property {boolean} [remote] - Use remote endpoint to spawn the controllers. Defaults to `true` when not in node.
* @property {string} [endpoint] - Endpoint URL to manage remote Controllers. (Defaults: 'http://localhost:43134').
* @property {boolean} [disposable=true] - A new repo is created and initialized for each invocation, as well as cleaned up automatically once the process exits.
* @property {string} [type] - The daemon type, see below the options:
* - go - spawn go-ipfs daemon node
* - js - spawn js-ipfs daemon node
* - proc - spawn in-process js-ipfs node
* @property {Object} [env] - Additional environment variables, passed to executing shell. Only applies for Daemon controllers.
* @property {Array} [args] - Custom cli args.
* @property {Object} [ipfsHttpModule] - Reference to a IPFS HTTP Client object.
* @property {Object} [ipfsModule] - Reference to a IPFS API object.
* @property {string} [ipfsBin] - Path to a IPFS exectutable.
* @property {IpfsOptions} [ipfsOptions] - Options for the IPFS node.
* @property {boolean} [forceKill] - Whether to use SIGKILL to quit a daemon that does not stop after `.stop()` is called. (default true)
* @property {number} [forceKillTimeout] - How long to wait before force killing a daemon in ms. (default 5000)
*/

/**
* @typedef {Object} ControllerOptionsOverrides
* @property {ControllerOptions} [js] - Pre-defined defaults options for **JS** controllers these are deep merged with options passed to `Factory.spawn(options)`.
* @property {ControllerOptions} [go] - Pre-defined defaults options for **Go** controllers these are deep merged with options passed to `Factory.spawn(options)`.
* @property {ControllerOptions} [proc] - Pre-defined defaults options for **Proc** controllers these are deep merged with options passed to `Factory.spawn(options)`.
*/
Loading

0 comments on commit 0f30547

Please sign in to comment.