-
-
Notifications
You must be signed in to change notification settings - Fork 648
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
POC: feat: enable to write jsx to streaming api #1913
Conversation
ddba75d
to
d5a8136
Compare
d5a8136
to
3ef835b
Compare
@sor4chi @yusukebe import { jsx } from '../jsx'
import { renderToReadableStream } from '../jsx/streaming'
import { StreamingApi } from './stream'
describe('StreamingApi', () => {
it('pipe(no promised hono/jsx)', async () => {
const Component1 = () => <span>foo</span>
const Component2 = () => <span>bar</span>
const { readable, writable } = new TransformStream()
const api = new StreamingApi(writable, readable)
const reader = api.responseReadable.getReader()
await api.pipe(renderToReadableStream(<Component1 />))
expect((await reader.read()).value).toEqual(new TextEncoder().encode('<span>foo</span>'))
await api.pipe(renderToReadableStream(<Component2 />))
expect((await reader.read()).value).toEqual(new TextEncoder().encode('<span>bar</span>'))
})
it('pipe(promised hono/jsx)', async () => {
const Component1 = async () => {
await new Promise((resolve) => setTimeout(resolve, 100))
return <span>foo</span>
}
const Component2 = async () => {
await new Promise((resolve) => setTimeout(resolve, 100))
return <span>bar</span>
}
const { readable, writable } = new TransformStream()
const api = new StreamingApi(writable, readable)
const reader = api.responseReadable.getReader()
await api.pipe(renderToReadableStream(<Component1 />))
expect((await reader.read()).value).toEqual(new TextEncoder().encode('<span>foo</span>'))
await api.pipe(renderToReadableStream(<Component2 />))
expect((await reader.read()).value).toEqual(new TextEncoder().encode('<span>bar</span>'))
})
}) |
Like this? const app = new Hono()
const HTML = () => (
<html lang='en'>
<body>
<template shadowrootmode='open'>
<slot name='component1'>
<p>Loading...</p>
</slot>
</template>
</body>
</html>
)
const Component = () => (
<div slot='component1'>
<h1>Hello Hono!</h1>
</div>
)
app.get('/', (c) => {
return stream(c, async (stream) => {
await stream.pipe(renderToReadableStream(<HTML />))
await stream.sleep(1000)
await stream.pipe(renderToReadableStream(<Component />))
})
}) |
@yusukebe |
How about writing this thing as a "snippet" on our website? |
Author should do the followings, if applicable
yarn denoify
to generate files for DenoIf JSX can be delivered via streamingAPI, as in the tweet below, it would be a nice match with the shadowrootmode of web components and allow components to be changed dynamically from the server without client JS.
https://x.com/shou_study/status/1743996737696764069?s=20
Demo:
Code
2024-01-08.3.22.52.mov