Skip to content

Commit

Permalink
feat: migrate to preact/compat (#190)
Browse files Browse the repository at this point in the history
* fix: add chunk hashes to all assets except sw

* test: update verify-dist tests

* chore: remove unused component

* tmp

* feat: basic router implemented

* fix: redirect page loads on subdomain

* chore: cleaned up code

* feat: minimal assets loaded on subdomain first-hit

* chore: remove runtimeChunk from webpack

* chore: remove unused deps

* feat: migrate to preact/compat

* chore: replace react with preact explicitly

* chore: remove implicit type definitions

* test: remove check css content thats in another chunk

* chore: fix tests after merging code from #182

* chore: apply suggestions from code review

* test: remove dist check for vendor-react asset
  • Loading branch information
SgtPooki committed Apr 16, 2024
1 parent bdc2979 commit 8c98f57
Show file tree
Hide file tree
Showing 20 changed files with 68 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
dependencyCheck: {
ignore: [
// .jsx files aren't checked properly.
'react-dom',
'preact',

// required by webpack
'webpack-cli',
Expand Down
80 changes: 12 additions & 68 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,14 @@
"@sgtpooki/file-type": "^1.0.1",
"debug": "^4.3.4",
"multiformats": "^13.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"preact": "^10.20.2"
},
"devDependencies": {
"@babel/core": "^7.24.3",
"@babel/preset-env": "^7.24.3",
"@babel/preset-react": "^7.24.1",
"@babel/preset-typescript": "^7.24.1",
"@playwright/test": "^1.42.1",
"@types/react": "^18.2.74",
"aegir": "^42.2.5",
"babel-loader": "^9.1.3",
"copy-webpack-plugin": "^12.0.2",
Expand Down
4 changes: 2 additions & 2 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Suspense } from 'react'
import React, { Suspense } from 'preact/compat'
import { RouteContext } from './context/router-context.jsx'
import './app.css'

function App (): JSX.Element {
function App (): React.JSX.Element {
const { currentRoute } = React.useContext(RouteContext)
return (
<Suspense fallback={<div>Loading...</div>}>
Expand Down
6 changes: 3 additions & 3 deletions src/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import React from 'preact/compat'

export default ({ handleSubmit, requestPath, setRequestPath }): JSX.Element => (
export default ({ handleSubmit, requestPath, setRequestPath }): React.JSX.Element => (
<form id='add-file' onSubmit={handleSubmit}>
<label htmlFor='inputContent' className='f5 ma0 pb2 aqua fw4 db'>CID (and path)</label>
<input
Expand All @@ -10,7 +10,7 @@ export default ({ handleSubmit, requestPath, setRequestPath }): JSX.Element => (
type='text'
placeholder='/ipfs/bafk.../path/to/file'
required
value={requestPath} onChange={(e) => setRequestPath(e.target.value)}
value={requestPath} onChange={(e) => setRequestPath(e.currentTarget.value)}
/>
</form>
)
4 changes: 2 additions & 2 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react'
import React from 'preact/compat'
import { RouteContext } from '../context/router-context.jsx'
import gearIcon from '../gear-icon.svg'
import ipfsLogo from '../ipfs-logo.svg'

export default function Header (): JSX.Element {
export default function Header (): React.JSX.Element {
const { gotoPage } = React.useContext(RouteContext)
return (
<header className='e2e-header flex items-center pa3 bg-navy bb bw3 b--aqua justify-between'>
Expand Down
4 changes: 2 additions & 2 deletions src/components/collapsible.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React, { useState } from 'preact/compat'

export interface CollapsibleProps {
children: React.ReactNode
Expand All @@ -7,7 +7,7 @@ export interface CollapsibleProps {
collapsed: boolean
}

export function Collapsible ({ children, collapsedLabel, expandedLabel, collapsed }: CollapsibleProps): JSX.Element {
export function Collapsible ({ children, collapsedLabel, expandedLabel, collapsed }: CollapsibleProps): React.JSX.Element {
const [cId] = useState(Math.random().toString(36).substring(7))
const [isCollapsed, setCollapsed] = useState(collapsed)

Expand Down
8 changes: 4 additions & 4 deletions src/components/input-validator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import { CID } from 'multiformats/cid'
import React from 'react'
import React from 'preact/compat'

/**
* Test files:
Expand All @@ -22,8 +22,8 @@ import React from 'react'
*
*/

function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children }): JSX.Element {
let errorElement: JSX.Element | null = null
function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children }): React.JSX.Element {
let errorElement: React.JSX.Element | null = null
if (requestPath == null || requestPath === '') {
errorElement = <span>Nothing to render yet. Enter an IPFS Path</span> // bafkreiezuss4xkt5gu256vjccx7vocoksxk77vwmdrpwoumfbbxcy2zowq
} else if (pathNamespacePrefix !== 'ipfs' && pathNamespacePrefix !== 'ipns') {
Expand All @@ -49,7 +49,7 @@ function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children })
</>
}

export default function InputValidator ({ requestPath }: { requestPath: string }): JSX.Element {
export default function InputValidator ({ requestPath }: { requestPath: string }): React.JSX.Element {
/**
* requestPath may be any of the following formats:
*
Expand Down
6 changes: 3 additions & 3 deletions src/components/local-storage-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'
import React, { useEffect, useState } from 'preact/compat'

export interface LocalStorageInputProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
localStorageKey: string
Expand All @@ -16,7 +16,7 @@ const defaultValidationFunction = (value: string): Error | null => {
return err as Error
}
}
export default ({ localStorageKey, label, placeholder, validationFn, defaultValue, ...props }: LocalStorageInputProps): JSX.Element => {
export default ({ localStorageKey, label, placeholder, validationFn, defaultValue, ...props }: LocalStorageInputProps): React.JSX.Element => {
const [value, setValue] = useState(localStorage.getItem(localStorageKey) ?? defaultValue)
const [error, setError] = useState<null | Error>(null)

Expand Down Expand Up @@ -47,7 +47,7 @@ export default ({ localStorageKey, label, placeholder, validationFn, defaultValu
type='text'
placeholder={placeholder}
value={value}
onChange={(e) => { setValue(e.target.value) }}
onChange={(e) => { setValue(e.currentTarget.value) }}
/>
{error != null && <span style={{ color: 'red' }}>{error.message}</span>}
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/local-storage-toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
Inspiration from https://dev.to/codebubb/create-a-simple-on-off-slide-toggle-with-css-db8
*/
import React, { useState } from 'react'
import React, { useState } from 'preact/compat'
import './local-storage-toggle.css'

interface LocalStorageToggleProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
Expand All @@ -17,7 +17,7 @@ export const LocalStorageToggle: React.FC<LocalStorageToggleProps> = ({ localSto
})

const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
const newValue = event.target.checked
const newValue = event.currentTarget.checked
setIsChecked(newValue)
localStorage.setItem(localStorageKey, String(newValue))
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/sw-ready-button.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { useContext, useMemo } from 'react'
import React, { useContext, useMemo } from 'preact/compat'
import { ServiceWorkerContext } from '../context/service-worker-context.jsx'
type ButtonProps = JSX.IntrinsicElements['button']
type ButtonProps = React.JSX.IntrinsicElements['button']

interface ServiceWorkerReadyButtonProps extends ButtonProps {
label: string
waitingLabel?: string
}

export const ServiceWorkerReadyButton = ({ className, label, waitingLabel, ...props }: ServiceWorkerReadyButtonProps): JSX.Element => {
export const ServiceWorkerReadyButton = ({ className, label, waitingLabel, ...props }: ServiceWorkerReadyButtonProps): React.JSX.Element => {
const { isServiceWorkerRegistered } = useContext(ServiceWorkerContext)

const buttonClasses = new Set(['button-reset', 'pv3', 'tc', 'bn', 'white', 'w-100', 'cursor-disabled', 'bg-gray'])
Expand Down
4 changes: 2 additions & 2 deletions src/context/config-context.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { createContext, useState } from 'react'
import React, { createContext, useState } from 'preact/compat'
import { isConfigPage } from '../lib/is-config-page.js'

const isLoadedInIframe = window.self !== window.top
Expand All @@ -8,7 +8,7 @@ export const ConfigContext = createContext({
setConfigExpanded: (value: boolean) => {}
})

export const ConfigProvider = ({ children }: { children: JSX.Element[] | JSX.Element, expanded?: boolean }): JSX.Element => {
export const ConfigProvider = ({ children }: { children: React.JSX.Element[] | React.JSX.Element, expanded?: boolean }): React.JSX.Element => {
const [isConfigExpanded, setConfigExpanded] = useState(isConfigPage(window.location.hash))
const isExplicitlyLoadedConfigPage = isConfigPage(window.location.hash)

Expand Down
6 changes: 3 additions & 3 deletions src/context/router-context.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useCallback, useEffect } from 'react'
import React, { useCallback, useEffect } from 'preact/compat'

export interface Route {
default?: boolean
path?: string
shouldRender?(): Promise<boolean>
component: React.LazyExoticComponent<(...args: any[]) => React.JSX.Element | null>
component(...args: any[]): React.JSX.Element | null
}

export const RouteContext = React.createContext<{
Expand All @@ -13,7 +13,7 @@ export const RouteContext = React.createContext<{
gotoPage(route?: string): void
}>({ currentRoute: undefined, gotoPage: () => {} })

export const RouterProvider = ({ children, routes }: { children: React.ReactNode, routes: Route[] }): JSX.Element => {
export const RouterProvider = ({ children, routes }: { children: React.ReactNode, routes: Route[] }): React.JSX.Element => {
const [currentRoute, setCurrentRoute] = React.useState<Route | undefined>(undefined)
/**
* The default route is the first route in the list of routes,
Expand Down
4 changes: 2 additions & 2 deletions src/context/service-worker-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* After the service worker is loaded. Usually any react code isn't loaded, but some edge cases are:
* 1. The page being loaded using some /ip[fn]s/<path> url, but subdomain isolation is supported, so we need to redirect to the isolated origin
*/
import React, { createContext, useEffect, useState } from 'react'
import React, { createContext, useEffect, useState } from 'preact/compat'
import { getRedirectUrl, isDeregisterRequest } from '../lib/deregister-request.js'
import { translateIpfsRedirectUrl } from '../lib/ipfs-hosted-redirect-utils.js'
import { error, trace } from '../lib/logger.js'
Expand All @@ -23,7 +23,7 @@ export const ServiceWorkerContext = createContext({
isServiceWorkerRegistered: false
})

export const ServiceWorkerProvider = ({ children }): JSX.Element => {
export const ServiceWorkerProvider = ({ children }): React.JSX.Element => {
const [isServiceWorkerRegistered, setIsServiceWorkerRegistered] = useState(false)

const windowLocation = translateIpfsRedirectUrl(window.location.href)
Expand Down
Loading

0 comments on commit 8c98f57

Please sign in to comment.