ipfs-examples/helia-examples

Usage with typescript ?

BjrInt opened this issue · 1 comments

It seems like there is no example using Typescript.
I have tried using the HeliaProvider component boilerplate code in Typescript, but this lead to several type errors.

I figured that createHelia returns a new Helia instance that is exported by @helia/interface, from there I was able to amend my index.d.ts file:

declare global {
  interface Window {
    helia: import('@helia/interface').Helia
  }
}

Here is the type annotated version of the file mentioned above. There is a type error emerging at line 38 (in the if window.helia block) (setFs(unixfs(helia))) that I commented below, I'm not sure this can be ignored considering how state updates happen in React.
For context, the helia state is initially set to null so when calling the unixFs(), if the state updates are batched it is possible that it is still null in the line below. Could it be replaced by setFs(unixfs(window.helia)) ?

import { unixfs, UnixFS } from '@helia/unixfs'
import { createHelia } from 'helia'
import { Helia } from '@helia/interface'
import {
  useEffect,
  useState,
  useCallback,
  createContext,
  ReactNode
} from 'react'

export type HeliaContextType = {
  helia: Helia | null
  fs: UnixFS | null
  error: boolean
  starting: boolean
}

export const HeliaContext = createContext<HeliaContextType>({
  helia: null,
  fs: null,
  error: false,
  starting: true
})

export const HeliaProvider = ({ children }: { children: ReactNode}) => {
  const [helia, setHelia] = useState<Helia | null>(null)
  const [fs, setFs] = useState<UnixFS | null>(null)
  const [starting, setStarting] = useState(true)
  const [error, setError] = useState(false)

  const startHelia = useCallback(async () => {
    if (helia) {
      console.info('helia already started')
    } else if (window.helia) {
      console.info('found a windowed instance of helia, populating ...')
      setHelia(window.helia)
      
      // Type error below: 
      // Argument of type null is not assignable to parameter of type Blockstore
      setFs(unixfs(helia))
      setStarting(false)
    } else {
      try {
        console.info('Starting Helia')
        const helia = await createHelia()
        setHelia(helia)
        setFs(unixfs(helia))
        setStarting(false)
      } catch (e) {
        console.error(e)
        setError(true)
      }
    }
  }, [])

  useEffect(() => {
    startHelia()
  }, [])

  return (
    <HeliaContext.Provider
      value={{
        helia,
        fs,
        error,
        starting
      }}
    >{children}</HeliaContext.Provider>
  )
}

Would gladly open a PR for the issues mentionned, but I'm not sure I'm doing this right.

BjrInt commented

A typescript example was added to the repository.