Skip to content
This repository was archived by the owner on Nov 25, 2023. It is now read-only.

Commit e6e2f8f

Browse files
committed
base typescript refactor
1 parent d20608c commit e6e2f8f

24 files changed

+293
-1132
lines changed

commands/index.js renamed to commands/index.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import React from 'react';
2-
import {TitleCard} from '../components/Title';
32
import {version, description} from '../package.json';
43
import {Box, Newline, Text} from "ink";
54

65
/// Displays help info
76
const Hello = () => <Box flexDirection="column">
8-
<TitleCard />
97
<Box
108
margin={1}
11-
color="white"
129
flexDirection="column"
1310
>
1411
<Text>Version: {version}</Text>

commands/join.js renamed to commands/join.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import useHyper from "../hooks/useHyper.js";
2+
import useHyper from "../hooks/useHyper";
33
import {SessionInfo} from '../components/Title'
44
import PropTypes from "prop-types";
55
import FileTree from "../components/FileTree";
@@ -11,8 +11,14 @@ import Loader from "../components/Loader";
1111
import useRemoteRegistry from "../hooks/useRemoteRegistry";
1212
import useDriveDownload from "../hooks/useDriveDownload";
1313

14+
interface IClientProps {
15+
dir: string,
16+
forceOverwrite: boolean,
17+
sessionId: string,
18+
}
19+
1420
/// Joins an existing portal using a given `sessionId`
15-
const Client = ({ dir, forceOverwrite, sessionId }) => {
21+
const Client = ({ dir, forceOverwrite, sessionId }: IClientProps) => {
1622
const hyper = useHyper(sessionId)
1723
const {errors, loading: remoteLoading, remoteRegistry, registryRenderableArray} = useRemoteRegistry(dir, hyper?.hyperObj?.eventLog)
1824
useDriveDownload(dir, remoteRegistry, hyper?.hyperObj?.drive)

commands/new.js renamed to commands/new.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import useHyper from "../hooks/useHyper.js";
2+
import useHyper from "../hooks/useHyper";
33
import {SessionInfo} from '../components/Title'
44
import {Box} from "ink";
55
import PropTypes from "prop-types";
@@ -10,9 +10,13 @@ import CommandWrapper from "../components/CommandWrapper";
1010
import useLocalRegistry from "../hooks/useLocalRegistry";
1111
import useDriveSync from "../hooks/useDriveSync";
1212

13+
interface IHostProps {
14+
dir: string,
15+
}
16+
1317
/// Creates a new portal in the given directory.
1418
/// If no directory is provided, uses current working directory
15-
const Host = ({dir}) => {
19+
const Host = ({dir}: IHostProps) => {
1620
const hyper = useHyper()
1721
const {errors, loading, localRegistry, registryRenderableArray} = useLocalRegistry(dir, hyper?.hyperObj?.eventLog)
1822
useDriveSync(dir, localRegistry, hyper?.hyperObj?.drive)

components/CommandWrapper.js renamed to components/CommandWrapper.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import React from 'react'
22
import Loader from "./Loader";
33
import {Text} from "ink";
4-
import {TitleCard} from "./Title";
54

6-
export default ({loading, error, children}) => {
5+
interface ICommandWrapperProps {
6+
loading: boolean,
7+
error: string,
8+
children?: React.ReactNode,
9+
}
10+
11+
export default ({loading, error, children}: ICommandWrapperProps) => {
712
if (loading) {
813
return <Loader status="Initializing Hyperspace..." />
914
}

components/Errors.js renamed to components/Errors.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import React from 'react';
22
import {Box, Text} from "ink";
33

4-
export default ({errors}) => errors.length !== 0 &&
4+
interface IErrorsProps {
5+
errors: string[]
6+
}
7+
export default ({errors}: IErrorsProps) => errors.length !== 0 &&
58
<Box marginTop={2} flexDirection="column">
69
<Text color="red" bold>Errors:</Text>
710
{errors.slice(0, 3).map((error, i) => <Text key={i}>

components/FileTree.js renamed to components/FileTree.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import React from 'react'
22
import {Box, Text} from "ink";
3-
import {STATUS} from "../domain/registry";
3+
import {ITreeRepresentation, STATUS} from "../domain/registry";
44
import Loader from "./Loader";
55

6-
const StatusIndicator = ({status}) => {
6+
interface IStatusIndicatorProps {
7+
status: STATUS;
8+
}
9+
const StatusIndicator = ({status}: IStatusIndicatorProps) => {
710
switch (status) {
811
case STATUS.synced:
912
return <Text color="green"></Text>
@@ -15,7 +18,10 @@ const StatusIndicator = ({status}) => {
1518
}
1619
}
1720

18-
export default ({registry}) => {
21+
interface IFileTreeProps {
22+
registry: ITreeRepresentation[],
23+
}
24+
export default ({registry}: IFileTreeProps) => {
1925
const synced = registry.filter(f => f.status === STATUS.synced).length
2026
return <Box flexDirection="column" marginY={1}>
2127
<Text bold>Files</Text>

components/Loader.js renamed to components/Loader.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import React from 'react';
22
import { Text } from 'ink';
33
import Spinner from 'ink-spinner';
44

5-
export default ({status, color}) => (
5+
interface ILoaderProps {
6+
status?: string,
7+
color?: string,
8+
}
9+
export default ({status, color}: ILoaderProps) => (
610
<Text>
711
<Text color={color ?? "green"}>
812
<Spinner type="dots" />
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import React from "react";
22
import {Text} from "ink";
33

4-
export const SessionInfo = ({sessionId}) => <>
4+
interface ITitleProps {
5+
sessionId: string,
6+
}
7+
export const SessionInfo = ({sessionId}: ITitleProps) => <>
58
<Text bold>Session ID </Text>
69
<Text>{sessionId}</Text>
710
</>

domain/registry.js renamed to domain/registry.ts

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,56 @@
11
import path from 'path'
2-
import {registerWatcher} from "../fs/watcher";
2+
import {EventCallback, EventData, registerWatcher} from "../fs/watcher";
33
import {TrieNode} from "./trie";
4-
5-
export const STATUS = Object.freeze({
6-
unsynced: "unsynced",
7-
error: "error",
8-
synced: "synced",
9-
})
4+
import Hyperdrive from "hyperdrive";
5+
import {Feed} from "hyperspace";
6+
7+
export enum STATUS {
8+
unsynced,
9+
error,
10+
synced,
11+
}
12+
13+
export interface ITreeRepresentation {
14+
padding: number,
15+
name: string,
16+
isDir: boolean,
17+
status: STATUS,
18+
}
1019

1120
export class Registry {
21+
private readonly root: TrieNode;
22+
drive: Hyperdrive | undefined;
23+
errorCallback: (err: string) => void;
24+
rerender: () => void;
25+
private subscribers: EventCallback[];
26+
1227
constructor() {
13-
this.root = new TrieNode(this, null)
28+
this.root = new TrieNode(this, "")
1429
this.drive = undefined
1530
this.errorCallback = () => {}
1631
this.rerender = () => {}
1732
this.subscribers = []
1833
}
1934

20-
// registy error callback
21-
onError(fn) {
35+
// registry error callback
36+
onError(fn: (err: string) => {}) {
2237
this.errorCallback = fn
2338
return this
2439
}
2540

26-
onRerender(fn) {
41+
onRerender(fn: () => void) {
2742
this.rerender = fn
2843
return this
2944
}
3045

3146
// add subscriber to event stream
32-
addSubscriber(fn) {
47+
addSubscriber(fn: EventCallback) {
3348
this.subscribers.push(fn)
3449
return this
3550
}
3651

3752
// set remote hyperdrive
38-
setDrive(drive) {
53+
setDrive(drive: Hyperdrive) {
3954
this.drive = drive
4055
return this
4156
}
@@ -48,15 +63,15 @@ export class Registry {
4863
return this.root.getChildren().map(child => child.download())
4964
}
5065

51-
size() {
66+
size(): number {
5267
return this.getTree().length
5368
}
5469

5570
// returns pre-order traversal of all nodes
5671
// in trie
57-
getTree() {
58-
const output = []
59-
const toStringRecur = (indent, node) => {
72+
getTree(): ITreeRepresentation[] {
73+
const output: ITreeRepresentation[] = []
74+
const toStringRecur = (indent: number, node: TrieNode) => {
6075
if (!node) {
6176
return
6277
}
@@ -80,7 +95,7 @@ export class Registry {
8095
}
8196

8297
// insert an entry into the registry
83-
insert(pathSegments, isDir = false) {
98+
insert(pathSegments: string[], isDir = false): void {
8499
let cur = this.root
85100
pathSegments.forEach(segment => {
86101
if (!cur.children[segment]) {
@@ -96,30 +111,30 @@ export class Registry {
96111

97112
// removes an entry from the registry
98113
// does nothing if node/dir is not present
99-
remove(pathSegments, isDir = false) {
114+
remove(pathSegments: string[], isDir = false): void {
100115
const node = this.find(pathSegments)
101116

102117
// only remove if node is present
103118
// and is a directory remove on a directory
104119
if (node && (isDir ? node.isDir : !node.isDir)) {
105120
const parent = node.parent
106-
delete parent.children[node.key]
121+
delete parent?.children[node.key]
107122
}
108123
}
109124

110125
// attempts to return entry with given path segments
111126
// returns false if not present
112-
find(pathSegments) {
113-
return pathSegments.reduce((cur, segment) => {
114-
if (!(cur.children && cur.children[segment])) {
115-
return false
127+
find(pathSegments: string[]): TrieNode | null {
128+
return pathSegments.reduce((cur: TrieNode | null, segment) => {
129+
if (!cur || !(cur.children && cur.children[segment])) {
130+
return null
116131
}
117132
return cur.children[segment]
118133
}, this.root)
119134
}
120135

121136
// parse events emitted from fs watcher
122-
parseEvt({ path: targetPath, status, isDir }) {
137+
parseEvt({ path: targetPath, status, isDir }: EventData) {
123138
if (status === 'genesis') return
124139
const pathSegments = targetPath.split(path.sep)
125140
switch (status) {
@@ -128,22 +143,24 @@ export class Registry {
128143
break
129144
case 'modify':
130145
const modNode = this.find(pathSegments)
131-
modNode.status = STATUS.unsynced
146+
if (modNode) {
147+
modNode.status = STATUS.unsynced
148+
}
132149
break
133150
case 'delete':
134151
this.remove(pathSegments, isDir)
135152
break
136153
}
137154
}
138155

139-
_onChangeCallback(data) {
156+
_onChangeCallback(data: EventData) {
140157
this.parseEvt(data)
141158
this.subscribers.forEach(fn => fn(data))
142159
this.rerender()
143160
}
144161

145162
// watch local directory for changes
146-
watch(dir, onReady) {
163+
watch(dir: string, onReady: () => void) {
147164
registerWatcher(
148165
dir,
149166
data => this._onChangeCallback(data),
@@ -153,9 +170,9 @@ export class Registry {
153170
}
154171

155172
// subscribe to remote eventLog hypercore feed
156-
subscribeRemote(eventLog, onReady) {
157-
const process = (data) => {
158-
this._onChangeCallback(JSON.parse(data))
173+
subscribeRemote(eventLog: Feed, onReady: () => void) {
174+
const process = (data: string) => {
175+
this._onChangeCallback(JSON.parse(data) as EventData)
159176
this.rerender()
160177
}
161178

0 commit comments

Comments
 (0)