Skip to content

Commit

Permalink
wip: rewrite in typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Jan 24, 2023
1 parent 2b129c7 commit e6e13ec
Show file tree
Hide file tree
Showing 421 changed files with 6,247 additions and 4,516 deletions.
6 changes: 3 additions & 3 deletions .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import EchoServer from 'aegir/echo-server'
* @typedef {object} BeforeType
* @property {import('ipfsd-ctl').Controller} server
* @property {EchoServer} echoServer
* @property {typeof import('./test/utils/mock-pinning-service.js')} pinningService
* @property {typeof import('./dist/test/utils/mock-pinning-service.js')} pinningService
* @property {Record<string, string>} env
*/
/** @type {import('aegir').PartialOptions} */
Expand All @@ -21,13 +21,13 @@ export default {
* @returns {Promise<BeforeType>}
*/
async before (options) {
const { PinningService } = await import('./test/utils/mock-pinning-service.js')
const { PinningService } = await import('./dist/test/utils/mock-pinning-service.js')
const pinningService = await PinningService.start()
const server = createServer({
port: 0
}, {
type: 'go',
kuboRpcModule: await import('./src/index.js'),
kuboRpcModule: await import('./dist/src/index.js'),
ipfsBin: (await import('go-ipfs')).default.path()
})

Expand Down
20 changes: 2 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@
},
"type": "module",
"types": "./dist/src/index.d.ts",
"typesVersions": {
"*": {
"*": [
"*",
"dist/*",
"dist/src/*",
"dist/src/*/index"
],
"src/*": [
"*",
"dist/*",
"dist/src/*",
"dist/src/*/index"
]
}
},
"files": [
"src",
"dist",
Expand All @@ -50,8 +34,8 @@
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./src/index.js",
"require": "./dist/src/index.js"
"require": "./dist/src/index.js",
"import": "./dist/src/index.js"
}
},
"eslintConfig": {
Expand Down
63 changes: 24 additions & 39 deletions src/add-all.js → src/add-all.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
import { CID } from 'multiformats/cid'
import { objectToCamel } from './lib/object-to-camel.js'
import { configure } from './lib/configure.js'
import { multipartRequest } from 'ipfs-core-utils/multipart-request'
import { toUrlSearchParams } from './lib/to-url-search-params.js'
import { abortSignal } from './lib/abort-signal.js'
import type { AddAllOptions, AddProgressFn, AddResult } from './root.js'
import type { Client } from './lib/core.js'
import type { ImportCandidateStream, IPFSUtilsHttpUploadProgressFn } from './index.js'

export const createAddAll = configure((api) => {
/**
* @type {import('./types.js').RootAPI["addAll"]}
*/
async function * addAll (source, options = {}) {
export function createAddAll (client: Client) {
async function * addAll (source: ImportCandidateStream, options?: AddAllOptions): AsyncIterable<AddResult> {
// allow aborting requests on body errors
const controller = new AbortController()
const signal = abortSignal(controller.signal, options.signal)
const signal = abortSignal(controller.signal, options?.signal)
const { headers, body, total, parts } =
await multipartRequest(source, controller, options.headers)
await multipartRequest(source, controller, options?.headers)

// In browser response body only starts streaming once upload is
// complete, at which point all the progress updates are invalid. If
// length of the content is computable we can interpret progress from
// `{ total, loaded}` passed to `onUploadProgress` and `multipart.total`
// in which case we disable progress updates to be written out.
const [progressFn, onUploadProgress] = typeof options.progress === 'function'
const [progressFn, onUploadProgress] = typeof options?.progress === 'function'
? createProgressHandler(total, parts, options.progress)
: [undefined, undefined]

const res = await api.post('add', {
const res = await client.post('add', {
searchParams: toUrlSearchParams({
'stream-channels': true,
...options,
Expand All @@ -42,36 +41,32 @@ export const createAddAll = configure((api) => {

if (file.hash !== undefined) {
yield toCoreInterface(file)
} else if (progressFn) {
progressFn(file.bytes || 0, file.name)
} else if (progressFn != null) {
progressFn(file.bytes ?? 0, file.name)
}
}
}
return addAll
})
}

interface ProgressPart {
name: string
start: number
end: number
}

/**
* Returns simple progress callback when content length isn't computable or a
* progress event handler that calculates progress from upload progress events.
*
* @param {number} total
* @param {{name:string, start:number, end:number}[]|null} parts
* @param {import('./types.js').IPFSCoreAddProgressFn} progress
* @returns {[import('./types.js').IPFSCoreAddProgressFn|undefined, import('./types.js').IPFSUtilsHttpUploadProgressFn|undefined]}
*/
const createProgressHandler = (total, parts, progress) =>
parts ? [undefined, createOnUploadProgress(total, parts, progress)] : [progress, undefined]
const createProgressHandler = (total: number, parts: ProgressPart[]|null, progress: AddProgressFn): [AddProgressFn|undefined, IPFSUtilsHttpUploadProgressFn|undefined] =>
parts != null ? [undefined, createOnUploadProgress(total, parts, progress)] : [progress, undefined]

/**
* Creates a progress handler that interpolates progress from upload progress
* events and total size of the content that is added.
*
* @param {number} size - actual content size
* @param {{name:string, start:number, end:number}[]} parts
* @param {import('./types.js').IPFSCoreAddProgressFn} progress
* @returns {import('./types.js').IPFSUtilsHttpUploadProgressFn}
*/
const createOnUploadProgress = (size, parts, progress) => {
const createOnUploadProgress = (size: number, parts: ProgressPart[], progress: AddProgressFn): IPFSUtilsHttpUploadProgressFn => {
let index = 0
const count = parts.length
return ({ loaded, total }) => {
Expand All @@ -93,18 +88,8 @@ const createOnUploadProgress = (size, parts, progress) => {
}
}

/**
* @param {object} input
* @param {string} input.name
* @param {string} input.hash
* @param {string} input.size
* @param {string} [input.mode]
* @param {number} [input.mtime]
* @param {number} [input.mtimeNsecs]
*/
function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) {
/** @type {import('./types.js').AddResult} */
const output = {
function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }: any) {
const output: AddResult = {
path: name,
cid: CID.parse(hash),
size: parseInt(size)
Expand All @@ -117,7 +102,7 @@ function toCoreInterface ({ name, hash, size, mode, mtime, mtimeNsecs }) {
if (mtime != null) {
output.mtime = {
secs: mtime,
nsecs: mtimeNsecs || 0
nsecs: mtimeNsecs ?? 0
}
}

Expand Down
24 changes: 0 additions & 24 deletions src/add.js

This file was deleted.

18 changes: 18 additions & 0 deletions src/add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import last from 'it-last'
import { normaliseInput } from 'ipfs-core-utils/files/normalise-input-single'
import { createAddAll } from './add-all.js'
import type { Client } from './lib/core.js'
import type { AddOptions, AddResult } from './root.js'
import type { ImportCandidate } from './index.js'

export function createAdd (client: Client) {
const all = createAddAll(client)
async function add (input: ImportCandidate, options?: AddOptions): Promise<AddResult> {
const source = normaliseInput(input)
// @ts-expect-error - all may return undefined if source is empty
const addAllPromise = all(source, options)
// @ts-expect-error - last may return undefined if source is empty
return await last(addAllPromise)
}
return add
}
17 changes: 0 additions & 17 deletions src/bitswap/index.js

This file was deleted.

56 changes: 56 additions & 0 deletions src/bitswap/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createWantlist } from './wantlist.js'
import { createStat } from './stat.js'
import type { PeerId } from '@libp2p/interface-peer-id'
import type { CID } from 'multiformats'
import type { Client } from '../lib/core.js'
import type { ClientOptions } from '../index.js'

export function createBitswap (client: Client): BitswapAPI {
// TODO: https://github.com/ipfs/js-kubo-rpc-client/issues/99
return {
wantlist: createWantlist(client),
stat: createStat(client)
}
}

export interface WantlistOptions extends ClientOptions {
peer: PeerId
}

export interface BitswapAPI {
/**
* Returns the wantlist for your node
*
* @example
* ```js
* const list = await ipfs.bitswap.wantlist()
* console.log(list)
* // [ CID('QmHash') ]
* ```
*/
wantlist: (options?: WantlistOptions) => Promise<CID[]>

/**
* Show diagnostic information on the bitswap agent.
* Note: `bitswap.stat` and `stats.bitswap` can be used interchangeably.
*
* @example
* ```js
* const stats = await ipfs.bitswap.stat()
* console.log(stats)
* ```
*/
stat: (options?: ClientOptions) => Promise<Stats>
}

export interface Stats {
provideBufLen: number
wantlist: CID[]
peers: PeerId[]
blocksReceived: bigint
dataReceived: bigint
blocksSent: bigint
dataSent: bigint
dupBlksReceived: bigint
dupDataReceived: bigint
}
29 changes: 13 additions & 16 deletions src/bitswap/stat.js → src/bitswap/stat.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
import { CID } from 'multiformats/cid'
import { configure } from '../lib/configure.js'
import { toUrlSearchParams } from '../lib/to-url-search-params.js'
import { peerIdFromString } from '@libp2p/peer-id'
import type { Stats } from './index.js'
import type { Client } from '../lib/core.js'
import type { ClientOptions } from '../index.js'

export const createStat = configure(api => {
/**
* @type {import('../types').BitswapAPI["stat"]}
*/
async function stat (options = {}) {
const res = await api.post('bitswap/stat', {
export function createStat (client: Client) {
async function stat (options?: ClientOptions): Promise<Stats> {
const res = await client.post('bitswap/stat', {
searchParams: toUrlSearchParams(options),
signal: options.signal,
headers: options.headers
signal: options?.signal,
headers: options?.headers
})

return toCoreInterface(await res.json())
}

return stat
})
}

/**
* @param {any} res
*/
function toCoreInterface (res) {
function toCoreInterface (res: any): Stats {
return {
provideBufLen: res.ProvideBufLen,
wantlist: (res.Wantlist || []).map((/** @type {{ '/': string }} */ k) => CID.parse(k['/'])),
peers: (res.Peers || []).map((/** @type {string} */ str) => peerIdFromString(str)),
wantlist: (res.Wantlist ?? []).map((k: Record<string, any>) => CID.parse(k['/'])),
peers: (res.Peers ?? []).map((str: string) => peerIdFromString(str)),
blocksReceived: BigInt(res.BlocksReceived),
dataReceived: BigInt(res.DataReceived),
blocksSent: BigInt(res.BlocksSent),
Expand Down
22 changes: 0 additions & 22 deletions src/bitswap/wantlist-for-peer.js

This file was deleted.

19 changes: 0 additions & 19 deletions src/bitswap/wantlist.js

This file was deleted.

Loading

0 comments on commit e6e13ec

Please sign in to comment.