Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce Service Worker Adapter #3062

Merged
merged 8 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jsr.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"./vercel": "./src/adapter/vercel/index.ts",
"./netlify": "./src/adapter/netlify/index.ts",
"./lambda-edge": "./src/adapter/lambda-edge/index.ts",
"./service-worker": "./src/adapter/service-worker/index.ts",
"./testing": "./src/helper/testing/index.ts",
"./dev": "./src/helper/dev/index.ts",
"./ws": "./src/helper/websocket/index.ts",
Expand Down
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,11 @@
"import": "./dist/adapter/lambda-edge/index.js",
"require": "./dist/cjs/adapter/lambda-edge/index.js"
},
"./service-worker": {
"types": "./dist/types/adapter/service-worker/index.d.ts",
"import": "./dist/adapter/service-worker/index.js",
"require": "./dist/cjs/adapter/service-worker/index.js"
},
"./testing": {
"types": "./dist/types/helper/testing/index.d.ts",
"import": "./dist/helper/testing/index.js",
Expand Down Expand Up @@ -527,6 +532,9 @@
"lambda-edge": [
"./dist/types/adapter/lambda-edge"
],
"service-worker": [
"./dist/types/adapter/service-worker"
],
"testing": [
"./dist/types/helper/testing"
],
Expand Down
57 changes: 57 additions & 0 deletions src/adapter/service-worker/handler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Hono } from '../../hono'
import { handle } from './handler'
import type { FetchEvent } from './types'

describe('handle', () => {
it('Success to fetch', async () => {
const app = new Hono()
app.get('/', (c) => {
return c.json({ hello: 'world' })
})
const handler = handle(app)
const json = await new Promise<Response>((resolve) => {
handler({
request: new Request('http://localhost/'),
respondWith(res) {
resolve(res)
},
} as FetchEvent)
}).then((res) => res.json())
expect(json).toStrictEqual({ hello: 'world' })
})
it('Fallback 404', async () => {
const app = new Hono()
const handler = handle(app, {
async fetch() {
return new Response('hello world')
},
})
const text = await new Promise<Response>((resolve) => {
handler({
request: new Request('http://localhost/'),
respondWith(res) {
resolve(res)
},
} as FetchEvent)
}).then((res) => res.text())
expect(text).toBe('hello world')
})
it('Do not fallback 404 when fetch is undefined', async () => {
const app = new Hono()
app.get('/', (c) => c.text('Not found', 404))
const handler = handle(app, {
fetch: undefined,
})
const result = await new Promise<Response>((resolve) =>
handler({
request: new Request('https://localhost/'),
respondWith(r) {
resolve(r)
},
} as FetchEvent)
)

expect(result.status).toBe(404)
expect(await result.text()).toBe('Not found')
})
})
33 changes: 33 additions & 0 deletions src/adapter/service-worker/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Handler for Service Worker
* @module
*/

import type { Hono } from '../../hono'
import type { FetchEvent } from './types'

type Handler = (evt: FetchEvent) => void

/**
* Adapter for Service Worker
*/
export const handle = (
app: Hono,
opts: {
fetch?: typeof fetch
} = {
fetch: fetch,
}
): Handler => {
return (evt) => {
evt.respondWith(
(async () => {
const res = await app.fetch(evt.request)
if (opts.fetch && res.status === 404) {
return await opts.fetch(evt.request)
}
return res
})()
)
}
}
5 changes: 5 additions & 0 deletions src/adapter/service-worker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Cloudflare Workers Adapter for Hono.
* @module
*/
export { handle } from './handler'

Check warning on line 5 in src/adapter/service-worker/index.ts

View check run for this annotation

Codecov / codecov/patch

src/adapter/service-worker/index.ts#L1-L5

Added lines #L1 - L5 were not covered by tests
14 changes: 14 additions & 0 deletions src/adapter/service-worker/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
interface ExtendableEvent extends Event {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
waitUntil(f: Promise<any>): void
}

export interface FetchEvent extends ExtendableEvent {
readonly clientId: string
readonly handled: Promise<undefined>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readonly preloadResponse: Promise<any>
readonly request: Request
readonly resultingClientId: string
respondWith(r: Response | PromiseLike<Response>): void
}