Skip to content

Commit

Permalink
fix: code cleanup, dep removal, & miscellaneous (#89)
Browse files Browse the repository at this point in the history
* refactor: remove unused helia andu se verified fetch

* chore: remove empty line

* fix: load config iframe using a hash fragment

fixes #88

* fix: load default config initially

* chore: fix linting errors

* chore: remove unused deps

* chore: re-add needed @helia/ipns dependency

* fix: set verifiedFetch when sw is activated

* chore: remove lib/heliaFetch and cleanup sw.ts (#95)

* fix: config loading on subdomains waits for updated config (#94)

* fix: config loading on subdomains waits for updated config

* fix: remove event.waitUtil inside channel.onmessagefrom

the activate event is fired when the service worker is first activated,
and then the channel.onmessagefrom event listener is set up.
by the time the channel receives any messages, the event passed to activate
will be done, and waitUntil has no effect (and throws an error)

* fix: service worker handles being disposed of

* fix: preload request from redirect page is handled by sw

* chore: better trace logging for config updates

---------

Co-authored-by: Daniel N <[email protected]>
Co-authored-by: Russell Dempsey <[email protected]>
  • Loading branch information
3 people authored Mar 9, 2024
1 parent 62169a1 commit 0a6d2f3
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 382 deletions.
53 changes: 3 additions & 50 deletions package-lock.json

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

9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,11 @@
}
},
"dependencies": {
"@helia/block-brokers": "^2.0.1",
"@helia/http": "^1.0.0",
"@helia/interface": "^4.0.0",
"@helia/ipns": "^6.0.0",
"@helia/routers": "^1.0.0",
"@helia/ipns": "^6.0.1",
"@helia/verified-fetch": "^1.1.0",
"@libp2p/logger": "^4.0.6",
"@sgtpooki/file-type": "^1.0.1",
"blockstore-idb": "^1.1.8",
"datastore-idb": "^2.1.8",
"debug": "^4.3.4",
"mime-types": "^2.1.35",

This comment has been minimized.

Copy link
@SgtPooki

SgtPooki Mar 9, 2024

Author Member

@lidel removal of this will also help with total size as mentioned in #93

"multiformats": "^11.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0"
Expand Down
14 changes: 9 additions & 5 deletions src/components/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { ConfigContext } from '../context/config-context.tsx'
import { HeliaServiceWorkerCommsChannel } from '../lib/channel.ts'
import { getConfig, loadConfigFromLocalStorage } from '../lib/config-db.ts'
import { LOCAL_STORAGE_KEYS } from '../lib/local-storage.ts'
import { Collapsible } from './collapsible'
import { trace } from '../lib/logger.ts'
import { Collapsible } from './collapsible.tsx'
import LocalStorageInput from './local-storage-input.tsx'
import { LocalStorageToggle } from './local-storage-toggle'
import { ServiceWorkerReadyButton } from './sw-ready-button.tsx'
Expand Down Expand Up @@ -45,15 +46,16 @@ export default (): JSX.Element | null => {
}
// we get the iframe origin from a query parameter called 'origin', if this is loaded in an iframe
// TODO: why we need this origin here? where is targetOrigin used?
const targetOrigin = decodeURIComponent(window.location.search.split('origin=')[1])
const targetOrigin = decodeURIComponent(window.location.hash.split('@origin=')[1])
const config = await getConfig()

trace('config-page: postMessage config to origin ', config, origin)
/**
* The reload page in the parent window is listening for this message, and then it passes a RELOAD_CONFIG message to the service worker
*/
window.parent?.postMessage({ source: 'helia-sw-config-iframe', target: 'PARENT', action: 'RELOAD_CONFIG', config }, {
targetOrigin
})
trace('config-page: RELOAD_CONFIG sent to parent window')
}, [])

useEffect(() => {
Expand All @@ -66,9 +68,11 @@ export default (): JSX.Element | null => {
const saveConfig = useCallback(async () => {
try {
await loadConfigFromLocalStorage()
trace('config-page: sending RELOAD_CONFIG to service worker')
// update the BASE_URL service worker
// TODO: use channel.messageAndWaitForResponse to ensure that the config is loaded before proceeding.
channel.postMessage({ target: 'SW', action: 'RELOAD_CONFIG' })
await channel.messageAndWaitForResponse('SW', { target: 'SW', action: 'RELOAD_CONFIG' })
// base_domain service worker is updated
trace('config-page: RELOAD_CONFIG_SUCCESS for %s', window.location.origin)
// update the <subdomain>.<namespace>.BASE_URL service worker
await postFromIframeToParentSw()
setConfigExpanded(false)
Expand Down
36 changes: 13 additions & 23 deletions src/get-helia.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,20 @@
import { trustlessGateway } from '@helia/block-brokers'
import { createHeliaHTTP } from '@helia/http'
import { delegatedHTTPRouting } from '@helia/routers'
import { IDBBlockstore } from 'blockstore-idb'
import { IDBDatastore } from 'datastore-idb'
import { dnsJsonOverHttps } from '@helia/ipns/dns-resolvers'
import { createVerifiedFetch, type VerifiedFetch } from '@helia/verified-fetch'
import { getConfig } from './lib/config-db.ts'
import { trace } from './lib/logger.ts'
import type { Helia } from '@helia/interface'
import { contentTypeParser } from './lib/content-type-parser.ts'
import { log } from './lib/logger.ts'

export async function getHelia (): Promise<Helia> {
export async function getVerifiedFetch (): Promise<VerifiedFetch> {
const config = await getConfig()
trace(`config-debug: got config for sw location ${self.location.origin}`, config)
const blockstore = new IDBBlockstore('./helia-sw/blockstore')
const datastore = new IDBDatastore('./helia-sw/datastore')
await blockstore.open()
await datastore.open()
log(`config-debug: got config for sw location ${self.location.origin}`, config)

const helia = await createHeliaHTTP({
blockstore,
datastore,
blockBrokers: [
trustlessGateway({
gateways: [...config.gateways, 'https://trustless-gateway.link']
})
],
routers: [...config.routers, 'https://delegated-ipfs.dev'].map(rUrl => delegatedHTTPRouting(rUrl))
const verifiedFetch = await createVerifiedFetch({
gateways: config.gateways ?? ['https://trustless-gateway.link'],
routers: config.routers ?? ['https://delegated-ipfs.dev'],
dnsResolvers: ['https://delegated-ipfs.dev/dns-query'].map(dnsJsonOverHttps)
}, {
contentTypeParser
})

return helia
return verifiedFetch
}
1 change: 1 addition & 0 deletions src/lib/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export enum COLORS {

export enum ChannelActions {
RELOAD_CONFIG = 'RELOAD_CONFIG',
RELOAD_CONFIG_SUCCESS = 'RELOAD_CONFIG_SUCCESS'
}
13 changes: 7 additions & 6 deletions src/lib/config-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export async function loadConfigFromLocalStorage (): Promise<void> {
if (typeof globalThis.localStorage !== 'undefined') {
const db = await openDatabase()
const localStorage = globalThis.localStorage
const localStorageGatewaysString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.gateways) ?? '[]'
const localStorageRoutersString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.routers) ?? '[]'
const localStorageGatewaysString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.gateways) ?? '["https://trustless-gateway.link"]'
const localStorageRoutersString = localStorage.getItem(LOCAL_STORAGE_KEYS.config.routers) ?? '["https://delegated-ipfs.dev"]'
const autoReload = localStorage.getItem(LOCAL_STORAGE_KEYS.config.autoReload) === 'true'
const debug = localStorage.getItem(LOCAL_STORAGE_KEYS.config.debug) ?? ''
const gateways = JSON.parse(localStorageGatewaysString)
Expand All @@ -71,8 +71,9 @@ export async function loadConfigFromLocalStorage (): Promise<void> {
}

export async function setConfig (config: ConfigDb): Promise<void> {
log('config-debug: setting config', config)
debugLib.enable(config.debug ?? '')
debugLib.enable(config.debug ?? '') // set debug level first.
log('config-debug: setting config %O for domain %s', config, window.location.origin)

const db = await openDatabase()
await setInDatabase(db, 'gateways', config.gateways)
await setInDatabase(db, 'routers', config.routers)
Expand All @@ -84,8 +85,8 @@ export async function setConfig (config: ConfigDb): Promise<void> {
export async function getConfig (): Promise<ConfigDb> {
const db = await openDatabase()

const gateways = await getFromDatabase(db, 'gateways') ?? []
const routers = await getFromDatabase(db, 'routers') ?? []
const gateways = await getFromDatabase(db, 'gateways') ?? ['https://trustless-gateway.link']
const routers = await getFromDatabase(db, 'routers') ?? ['https://delegated-ipfs.dev']
const autoReload = await getFromDatabase(db, 'autoReload') ?? false
const debug = await getFromDatabase(db, 'debug') ?? ''
debugLib.enable(debug)
Expand Down
47 changes: 47 additions & 0 deletions src/lib/content-type-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { type ContentTypeParser } from '@helia/verified-fetch'
import { fileTypeFromBuffer } from '@sgtpooki/file-type'

// default from verified-fetch is application/octect-stream, which forces a download. This is not what we want for MANY file types.
export const defaultMimeType = 'text/html'

export const contentTypeParser: ContentTypeParser = async (bytes, fileName) => {
const detectedType = (await fileTypeFromBuffer(bytes))?.mime
if (detectedType != null) {
return detectedType
}
if (fileName == null) {
// no other way to determine file-type.
return defaultMimeType
}

// no need to include file-types listed at https://github.com/SgtPooki/file-type#supported-file-types
switch (fileName.split('.').pop()) {
case 'css':
return 'text/css'
case 'html':
return 'text/html'
case 'js':
return 'application/javascript'
case 'json':
return 'application/json'
case 'txt':
return 'text/plain'
case 'woff2':
return 'font/woff2'
// see bottom of https://github.com/SgtPooki/file-type#supported-file-types
case 'svg':
return 'image/svg+xml'
case 'csv':
return 'text/csv'
case 'doc':
return 'application/msword'
case 'xls':
return 'application/vnd.ms-excel'
case 'ppt':
return 'application/vnd.ms-powerpoint'
case 'msi':
return 'application/x-msdownload'
default:
return defaultMimeType
}
}
Loading

0 comments on commit 0a6d2f3

Please sign in to comment.