Skip to content

Commit

Permalink
refactor (#2)
Browse files Browse the repository at this point in the history
* reafactor

* Fix deps and ready state

* add fixes

* use swarm sessions for replication

* dht changes

* coreKey -> publicKey

* simplify cleanup

* remove llll

* Update core.js
  • Loading branch information
cayasso authored Mar 26, 2023
1 parent 8dbe18b commit 20bc0a4
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 211 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
package-lock.json
yarn.lock
39 changes: 26 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ npm i use-hyper
Warning: this is experimental, and API might change until v1.

## Usage

Every hook requires the related library installed:

- `useCore` depends on `hypercore`.
- `useDHT` depends on `@hyperswarm/dht-relay`.
- `useSwarm` depends on `hyperswarm`.
Expand All @@ -20,30 +22,41 @@ If you import `useSwarm` then install this specific branch:
`npm i holepunchto/hyperswarm#add-swarm-session`

```javascript
import { useCore, useCoreEvent, useCoreWatch } from 'use-hyper/core'
import { useCore, useCoreEvent, useCoreWatch } from 'use-hyper'
import useDHT from 'use-hyper/dht'
import useSwarm from 'use-hyper/swarm'

function App () {
const [core, setCoreOptions] = useCore(RAM)

const coreOpened = useCoreEvent(core, 'ready', () => {})
const coreClosed = useCoreEvent(core, 'close', () => {})
const coreAppend = useCoreEvent(core, 'append', () => {})
const Child = () => {
const { core } = useCore()

const coreChanged = useCoreWatch(core, () => {}) // Trigger re-renders when core changes
const { core } = useCoreWatch(['append', 'close']) // updates on append and close events

const [writableCore] = useCore(RAM)
const [readableCore] = useCore(RAM, publicKey)
const { core } = useCoreEvent('append', () => {
console.log(core) // do something
})
}

const [dht] = useDHT() // Global DHT instance by default for now
const [swarm] = useSwarm(dht)
const App = () => {
return (
<Core storage={RAM} publicKey={key}>
<Child />
</Core>
)
}

// ...
export default () => {
return (
<DHT>
<Swarm>
<App />
</Swarm>
</DHT>
)
}
```

Every state like `core`, `dht`, or `swarm` starts being `null` but then gets updated with the corresponding object.

## License

MIT
141 changes: 0 additions & 141 deletions core.mjs

This file was deleted.

28 changes: 0 additions & 28 deletions dht.mjs

This file was deleted.

9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "use-hyper",
"version": "0.0.3",
"description": "React hooks for the hypercore-protocol stack",
"main": "",
"main": "./src/index.js",
"scripts": {
"test": "standard"
},
Expand All @@ -16,11 +16,16 @@
"url": "https://github.com/LuKks/use-hyper/issues"
},
"homepage": "https://github.com/LuKks/use-hyper",
"peerDependencies": {
"react": "*",
"react-dom": "*"
},
"devDependencies": {
"standard": "^17.0.0"
},
"dependencies": {
"b4a": "^1.6.2",
"b4a": "^1.6.3",
"safety-catch": "^1.0.2",
"sodium-universal": "^4.0.0"
}
}
90 changes: 90 additions & 0 deletions src/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React, {
useEffect,
useState,
useRef,
useContext,
createContext
} from 'react'
import safetyCatch from 'safety-catch'
import Hypercore from 'hypercore'

const CoreContext = createContext()

const EVENTS = [
'ready',
'append',
'close',
'peer-add',
'peer-remove',
'truncate'
]

export const Core = ({ children, storage, publicKey, ...options }) => {
const [core, setCore] = useState(null)
const deps = Object.values(options)

useEffect(() => {
if (!storage) return

const core = new Hypercore(storage, publicKey, options)
const onReady = () => setCore(core)
core.once('ready', onReady)
return () => {
core.off('ready', onReady)
core.close().catch(safetyCatch)
}
}, [storage, publicKey, ...deps])

if (!core) return null

return React.createElement(
CoreContext.Provider,
{ value: { core } },
children
)
}

export const useCore = () => {
const context = useContext(CoreContext)

if (context === undefined) {
throw new Error('useCore must be used within a Core component')
}

return context
}

export const useCoreEvent = (event, cb) => {
const { core } = useCore()
const fn = useRef(cb)

useEffect(() => {
fn.current = cb
}, [cb])

useEffect(() => {
if (!core || core?.closed) return

const listener = event => fn.current(event)
core.on(event, listener)
return () => core.off(event, listener)
}, [event, core])

return { core }
}

export const useCoreWatch = (events = EVENTS) => {
const { core } = useCore()
const [, update] = useState(0)

useEffect(() => {
if (!core || core?.closed) return

const onchange = () => update(i => i + 1)
events.forEach(event => core.on(event, onchange))
onchange()
return () => events.forEach(event => core.off(event, onchange))
}, [core, events])

return { core }
}
Loading

0 comments on commit 20bc0a4

Please sign in to comment.