Skip to content

Commit

Permalink
feat: upload progress ui (#1655)
Browse files Browse the repository at this point in the history
This PR adds visual feedback for then big files are imported:
progress bar + % status.

There is also new http-client and a bunch of required fixes.

* fix: broken file list stories
* feat: upload progress ui
* chore: integrate external changes
* fix: integrate new http client
* fix: jsdom problem
* fix(cid) switch circleci to new images
* fix(e2e): test/e2e/remote-api.test.js
  This makes E2E tests for remote API less flaky:
  - leverage expect-puppeteer where possible
  - tweak navigation so it is not impacted by connection-error state
  - force refresh of status page to avoid wait for manual refresh
  * fix(ci): E2E_IPFSD_TYPE=js npm run test:e2e
  js-ipfs changed CLI path at some point recently

Co-authored-by: Marcin Rataj <lidel@lidel.org>
  • Loading branch information
Gozala and lidel committed Feb 25, 2021
1 parent 6cbab77 commit f236694
Show file tree
Hide file tree
Showing 34 changed files with 27,753 additions and 18,748 deletions.
6 changes: 4 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
version: 2
version: 2.1
orbs:
browser-tools: circleci/browser-tools@1.1.0
jobs:
build:
docker:
- image: circleci/node:12.16.2-browsers-legacy
- image: cimg/node:14.15.4-browsers
environment:
NO_SANDBOX: true
steps:
Expand Down
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
REACT_APP_VERSION=$npm_package_version
SKIP_PREFLIGHT_CHECK=true
8 changes: 5 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
parser: "babel-eslint",
extends: ['react-app', 'standard', "plugin:jsx-a11y/recommended"],
plugins: ["jsx-a11y"]
parser: 'babel-eslint',
extends: ['react-app', 'standard', 'plugin:jsx-a11y/recommended'],
plugins: ['jsx-a11y'],
// ignore .ts files because it fails to parse it.
ignorePatterns: 'src/**/*.ts'
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ yarn-error.log*

.vscode
.idea
.eslintcache
168 changes: 79 additions & 89 deletions @types/ipfs/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,140 +1,134 @@
declare module "ipfs" {
import CID from "cids"
import Multiaddr from 'multiaddr'
import { Buffer } from "buffer"

export interface IPFSService extends CoreService {
pin: PinService
files: FileService
name: NameService
object: ObjectService
config: ConfigService
declare module 'ipfs' {
import type CID from 'cids'
import type Multiaddr from 'multiaddr'
import type { Buffer } from 'buffer'

declare export interface IPFSService extends CoreService {
pin: PinService;
files: FileService;
name: NameService;
object: ObjectService;
config: ConfigService;

stop(options?: TimeoutOptions): Promise<void>
}

export interface CoreService {
cat(pathOrCID: string | CID, options?: CatOptions): AsyncIterable<Buffer>
ls(pathOrCID: string | CID, options?: ListOptions): AsyncIterable<ListEntry>
add(file: FileContent | FileObject, options?: AddOptions): Promise<UnixFSEntry>
addAll(files: Iterable<FileContent | FileObject> | AsyncIterable<FileContent | FileObject> | ReadableStream<FileContent | FileObject>, options?: AddOptions): AsyncIterable<UnixFSEntry>
declare export interface CoreService {
cat(pathOrCID: string | CID, options?: CatOptions): AsyncIterable<Buffer>;
ls(pathOrCID: string | CID, options?: ListOptions): AsyncIterable<ListEntry>;
add(file: FileContent | FileObject, options?: AddOptions): Promise<UnixFSEntry>;
addAll(files: Iterable<FileContent | FileObject> | AsyncIterable<FileContent | FileObject> | ReadableStream<FileContent | FileObject>, options?: AddOptions): AsyncIterable<UnixFSEntry>;
}

export interface PinService {
add(cid: CID, options?: PinAddOptions): Promise<Pin[]>
ls(options?: PinListOptions): AsyncIterable<PinEntry>
rm(cid: CID, options?: PinRemoveOptions): Promise<Pin[]>
declare export interface PinService {
add(cid: CID, options?: PinAddOptions): Promise<Pin[]>;
ls(options?: PinListOptions): AsyncIterable<PinEntry>;
rm(cid: CID, options?: PinRemoveOptions): Promise<Pin[]>;
}

export interface FileService {
stat(path: string, options?: FSStatOptions): Promise<FileStat>
cp(from: string, to: string, options?: FSCopyOptions): Promise<void>
mv(from: string, to: string, options?: FSMoveOptions): Promise<void>
rm(path: string, options: FSRemoveOptions): Promise<void>
mkdir(path: string, options: FSMakDirectoryOptions): Promise<void>
declare export interface FileService {
stat(path: string, options?: FSStatOptions): Promise<FileStat>;
cp(from: string, to: string, options?: FSCopyOptions): Promise<void>;
mv(from: string, to: string, options?: FSMoveOptions): Promise<void>;
rm(path: string, options: FSRemoveOptions): Promise<void>;
mkdir(path: string, options: FSMakDirectoryOptions): Promise<void>;
}

export interface ConfigService {
get(key: string, options?: TimeoutOptions): Promise<Object>
getAll(options?: TimeoutOptions): Promise<Object>
set(key: string, value: string | number | null | boolean | Object, options?: TimeoutOptions): Promise<void>
replace(config: Object, options?: TimeoutOptions): Promise<void>
declare export interface ConfigService {
get(key: string, options?: TimeoutOptions): Promise<Object>;
getAll(options?: TimeoutOptions): Promise<Object>;
set(key: string, value: string | number | null | boolean | Object, options?: TimeoutOptions): Promise<void>;
replace(config: Object, options?: TimeoutOptions): Promise<void>;

profiles: ConfigProfiles
profiles: ConfigProfiles;
}

export interface ConfigProfiles {
list(options?: TimeoutOptions): Promise<Array<{ name: string, description: string }>>
apply(name: string, options?: { dryRun?: boolean } & TimeoutOptions): Promise<{ original: Object, updated: Object }>
declare export interface ConfigProfiles {
list(options?: TimeoutOptions): Promise<Array<{ name: string, description: string }>>;
apply(name: string, options?: { dryRun?: boolean } & TimeoutOptions): Promise<{ original: Object, updated: Object }>;
}

export interface NameService {
declare export interface NameService {
resolve(value: string, options?: NameResloveOptions): AsyncIterable<string>
}

export interface SwarmService {
declare export interface SwarmService {
connect(addr: Multiaddr, options?: TimeoutOptions): Promise<void>
}

export interface ObjectService {
new: (options?: ObjectNewOptions) => Promise<CID>
declare export interface ObjectService {
new: (options?: ObjectNewOptions) => Promise<CID>;
patch: ObjectPatchService
}

export interface ObjectPatchService {
declare export interface ObjectPatchService {
addLink(cid: CID, link: DAGLink, options?: TimeoutOptions): Promise<CID>
}

export type DAGLink = {
declare export type DAGLink = {
name: string,
size: number,
cid: CID
}

export type Pin = { cid: CID }
declare export type Pin = { cid: CID }

export type TimeoutOptions = {
declare export type TimeoutOptions = {
timeout?: number,
signal?: AbortSignal
}

export type PinAddOptions = TimeoutOptions & {
declare export type PinAddOptions = TimeoutOptions & {
recursive?: boolean,
}

export type PinType =
declare export type PinType =
| "recursive"
| "direct"
| "indirect"

export type PinEntry = {
declare export type PinEntry = {
cid: CID,
typ: PinType
}

export type PinListOptions = TimeoutOptions & {
declare export type PinListOptions = TimeoutOptions & {
paths?: string | CID | string[] | CID[],
type?: PinType
}

export type PinRemoveOptions = TimeoutOptions & {
declare export type PinRemoveOptions = TimeoutOptions & {
recursive?: boolean
}



export type FSStatOptions = TimeoutOptions & {
declare export type FSStatOptions = TimeoutOptions & {
hash?: boolean,
size?: boolean,
withLocal?: boolean
}



export type FSCopyOptions = TimeoutOptions & {
declare export type FSCopyOptions = TimeoutOptions & {
parents?: boolean,
flush?: boolean,
hashAlg?: string,
cidVersion?: number
}

export type FSMoveOptions = TimeoutOptions & {
declare export type FSMoveOptions = TimeoutOptions & {
parents?: boolean,
flush?: boolean,
hashAlg?: string,
cidVersion?: number
}



export type FSRemoveOptions = TimeoutOptions & {
declare export type FSRemoveOptions = TimeoutOptions & {
recursive?: boolean,
flush?: boolean,
hashAlg?: string,
cidVersion?: number
}

export type FSMakDirectoryOptions = TimeoutOptions & {
declare export type FSMakDirectoryOptions = TimeoutOptions & {
parents?: boolean,
mode?: number,
mtime?: UnixFSTime | Date | [number, number],
Expand All @@ -143,43 +137,42 @@ declare module "ipfs" {
cidVersion?: number
}

export type FileType =
declare export type FileType =
| 'file'
| 'directory'

export interface FileStat {
cid: CID
size: number
cumulativeSize: number
type: FileType
blocks: number
withLocality: boolean
local: boolean
sizeLocal: number
declare export interface FileStat {
cid: CID;
size: number;
cumulativeSize: number;
type: FileType;
blocks: number;
withLocality: boolean;
local: boolean;
sizeLocal: number;
}


export type NameResloveOptions = TimeoutOptions & {
declare export type NameResloveOptions = TimeoutOptions & {
recursive?: boolean,
nocache?: boolean
}

export type ObjectNewOptions = TimeoutOptions & {
declare export type ObjectNewOptions = TimeoutOptions & {
template?: string,
recursive?: boolean,
nocache?: boolean
}

export type CatOptions = TimeoutOptions & {
offset?: number
length?: number
declare export type CatOptions = TimeoutOptions & {
offset?: number;
length?: number;
}

export type ListOptions = TimeoutOptions & {
declare export type ListOptions = TimeoutOptions & {

}

export type ListEntry = {
declare export type ListEntry = {
depth: number,
name: string,
path: string,
Expand All @@ -192,55 +185,52 @@ declare module "ipfs" {
mtime: { secs: number, nsecs?: number }
}


type FileContent =
declare type FileContent =
| Uint8Array
| Blob
| String
| AsyncIterable<Uint8Array>
| ReadableStream<Uint8Array>

type FileObject = {
declare type FileObject = {
path?: string,
content?: FileContent,
mode?: number | string,
mtime?: Date | UnixFSTime | [number, number]
}

export type AddOptions = TimeoutOptions & {
declare export type AddOptions = TimeoutOptions & {
chunker?: string,
cidVersion?: number,
hashAlg?: number,
onlyHash?: boolean,
pin?: boolean,
progress?: (bytes: number) => void,
progress?: (bytes: number, name:string) => void,
rawLeaves?: boolean,
trickle?: boolean,
wrapWithDirectory?: boolean,
onUploadProgress?: (progress: LoadProgress) => void,
onDownloadProgress?: (progress: LoadProgress) => void
}

type LoadProgress = {
declare type LoadProgress = {
total: number,
loaded: number,
lengthComputable: boolean
}

export type UnixFSEntry = {
declare export type UnixFSEntry = {
path: string,
cid: CID,
mode: number,
mtime: UnixFSTime,
size: number
}


export type UnixFSTime = {
declare export type UnixFSTime = {
secs: number,
nsecs: number
}


export var IPFS: IPFSService
}
declare export var IPFS: IPFSService
}
10 changes: 10 additions & 0 deletions ipfs-core-types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Workaround https://github.com/ipfs/js-ipfs/issues/3494
declare module 'ipfs-core-types' {
import type { RootAPI as $RootAPI } from 'ipfs-core-types/src/root'
import type { AbortOptions as $AbortOptions, Await as $Await, AwaitIterable as $AwaitIterable } from 'ipfs-core-types/src/basic'

declare export interface RootAPI extends $RootAPI {}
declare export interface AbortOptions extends $AbortOptions {}
declare export type Await<T> = $Await<T>
declare export type AwaitIterable<T> = $AwaitIterable<T>
}
Loading

0 comments on commit f236694

Please sign in to comment.