From 537862507b23a2533ff113812d355d8cf38ff23a Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:04:36 +0900 Subject: [PATCH 01/13] refactor: move streaming helper to `streaming/sse.ts` --- src/helper/streaming/{index.test.ts => sse.test.ts} | 0 src/helper/streaming/{index.ts => sse.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/helper/streaming/{index.test.ts => sse.test.ts} (100%) rename src/helper/streaming/{index.ts => sse.ts} (100%) diff --git a/src/helper/streaming/index.test.ts b/src/helper/streaming/sse.test.ts similarity index 100% rename from src/helper/streaming/index.test.ts rename to src/helper/streaming/sse.test.ts diff --git a/src/helper/streaming/index.ts b/src/helper/streaming/sse.ts similarity index 100% rename from src/helper/streaming/index.ts rename to src/helper/streaming/sse.ts From 4f242807601a0e685e273d2f924dfa1c95b8ee12 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:05:26 +0900 Subject: [PATCH 02/13] feat: add streamSSE's export in streaming handler --- src/helper/streaming/index.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/helper/streaming/index.ts diff --git a/src/helper/streaming/index.ts b/src/helper/streaming/index.ts new file mode 100644 index 000000000..f607812b3 --- /dev/null +++ b/src/helper/streaming/index.ts @@ -0,0 +1 @@ +export { streamSSE } from './sse' From 5c981113b4c88bf2eca822f9bd212f58b464edd0 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:18:58 +0900 Subject: [PATCH 03/13] feat: move `stream` and `streamText` to streaming helper --- src/context.ts | 4 ++-- src/helper/streaming/index.ts | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/context.ts b/src/context.ts index 2a8f603d2..4d2e2f9f5 100644 --- a/src/context.ts +++ b/src/context.ts @@ -8,7 +8,7 @@ import type { StatusCode } from './utils/http-status' import { StreamingApi } from './utils/stream' import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types' -type HeaderRecord = Record +export type HeaderRecord = Record type Data = string | ArrayBuffer | ReadableStream export interface ExecutionContext { @@ -83,7 +83,7 @@ type ContextOptions = { notFoundHandler?: NotFoundHandler } -const TEXT_PLAIN = 'text/plain; charset=UTF-8' +export const TEXT_PLAIN = 'text/plain; charset=UTF-8' export class Context< // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/helper/streaming/index.ts b/src/helper/streaming/index.ts index f607812b3..398b2c6b2 100644 --- a/src/helper/streaming/index.ts +++ b/src/helper/streaming/index.ts @@ -1 +1,33 @@ +import { Context, HeaderRecord, TEXT_PLAIN } from '../../context' +import { StatusCode } from '../../utils/http-status' +import { StreamingApi } from '../../utils/stream' + export { streamSSE } from './sse' + +export const streamText = ( + c: Context, + cb: (stream: StreamingApi) => Promise, + arg?: StatusCode | ResponseInit, + headers?: HeaderRecord +): Response => { + headers ??= {} + c.header('content-type', TEXT_PLAIN) + c.header('x-content-type-options', 'nosniff') + c.header('transfer-encoding', 'chunked') + return stream(c, cb, arg, headers) +} + +export const stream = ( + c: Context, + cb: (stream: StreamingApi) => Promise, + arg?: StatusCode | ResponseInit, + headers?: HeaderRecord +): Response => { + const { readable, writable } = new TransformStream() + const stream = new StreamingApi(writable) + cb(stream).finally(() => stream.close()) + + return typeof arg === 'number' + ? c.newResponse(readable, arg, headers) + : c.newResponse(readable, arg) +} From a3cbc77e2f9612868fa5ea2eb4b71e1d79aad3dc Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:23:30 +0900 Subject: [PATCH 04/13] chore: add deprecated expression for `c.stream` and `c.streamText` --- src/context.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/context.ts b/src/context.ts index 4d2e2f9f5..89c7dea21 100644 --- a/src/context.ts +++ b/src/context.ts @@ -375,6 +375,9 @@ export class Context< return this.newResponse(null, status) } + /** @deprecated + * Use `streamText()` in `hono/helper/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. + */ streamText = ( cb: (stream: StreamingApi) => Promise, arg?: StatusCode | ResponseInit, @@ -387,6 +390,9 @@ export class Context< return this.stream(cb, arg, headers) } + /** @deprecated + * Use `stream()` in `hono/helper/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. + */ stream = ( cb: (stream: StreamingApi) => Promise, arg?: StatusCode | ResponseInit, From 3e3a5c9e1ad6d5c35a3ef0e29568e65664cf53c7 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:27:12 +0900 Subject: [PATCH 05/13] fix: use `stream` helper in streamSSE --- src/helper/streaming/sse.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/helper/streaming/sse.ts b/src/helper/streaming/sse.ts index 669c5e399..56d3dd79f 100644 --- a/src/helper/streaming/sse.ts +++ b/src/helper/streaming/sse.ts @@ -1,3 +1,4 @@ +import { stream } from '.' import type { Context } from '../../context' import { StreamingApi } from '../../utils/stream' @@ -37,7 +38,7 @@ const setSSEHeaders = (context: Context) => { } export const streamSSE = (c: Context, cb: (stream: SSEStreamingApi) => Promise) => { - return c.stream(async (originalStream: StreamingApi) => { + return stream(c, async (originalStream: StreamingApi) => { const { readable, writable } = new TransformStream() const stream = new SSEStreamingApi(writable) From 3e415c97804e18fe3692e2862d78683ce9eeac83 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:29:18 +0900 Subject: [PATCH 06/13] refactor: move `streamText` to `text.ts` --- src/helper/streaming/index.ts | 22 +++++----------------- src/helper/streaming/sse.ts | 2 +- src/helper/streaming/text.ts | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 src/helper/streaming/text.ts diff --git a/src/helper/streaming/index.ts b/src/helper/streaming/index.ts index 398b2c6b2..df276cc07 100644 --- a/src/helper/streaming/index.ts +++ b/src/helper/streaming/index.ts @@ -1,22 +1,7 @@ -import { Context, HeaderRecord, TEXT_PLAIN } from '../../context' -import { StatusCode } from '../../utils/http-status' +import type { Context, HeaderRecord } from '../../context' +import type { StatusCode } from '../../utils/http-status' import { StreamingApi } from '../../utils/stream' -export { streamSSE } from './sse' - -export const streamText = ( - c: Context, - cb: (stream: StreamingApi) => Promise, - arg?: StatusCode | ResponseInit, - headers?: HeaderRecord -): Response => { - headers ??= {} - c.header('content-type', TEXT_PLAIN) - c.header('x-content-type-options', 'nosniff') - c.header('transfer-encoding', 'chunked') - return stream(c, cb, arg, headers) -} - export const stream = ( c: Context, cb: (stream: StreamingApi) => Promise, @@ -31,3 +16,6 @@ export const stream = ( ? c.newResponse(readable, arg, headers) : c.newResponse(readable, arg) } + +export { streamSSE } from './sse' +export { streamText } from './text' diff --git a/src/helper/streaming/sse.ts b/src/helper/streaming/sse.ts index 56d3dd79f..0f43287ce 100644 --- a/src/helper/streaming/sse.ts +++ b/src/helper/streaming/sse.ts @@ -1,6 +1,6 @@ -import { stream } from '.' import type { Context } from '../../context' import { StreamingApi } from '../../utils/stream' +import { stream } from '.' interface SSEMessage { data: string diff --git a/src/helper/streaming/text.ts b/src/helper/streaming/text.ts new file mode 100644 index 000000000..45d592bcd --- /dev/null +++ b/src/helper/streaming/text.ts @@ -0,0 +1,18 @@ +import type { Context, HeaderRecord } from '../../context' +import { TEXT_PLAIN } from '../../context' +import type { StatusCode } from '../../utils/http-status' +import type { StreamingApi } from '../../utils/stream' +import { stream } from '.' + +export const streamText = ( + c: Context, + cb: (stream: StreamingApi) => Promise, + arg?: StatusCode | ResponseInit, + headers?: HeaderRecord +): Response => { + headers ??= {} + c.header('content-type', TEXT_PLAIN) + c.header('x-content-type-options', 'nosniff') + c.header('transfer-encoding', 'chunked') + return stream(c, cb, arg, headers) +} From 0f575bfb216513127e055c1dc45a2327a13d2825 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:37:55 +0900 Subject: [PATCH 07/13] test: add some case to `stream` and `streamText` --- src/helper/streaming/index.test.ts | 28 ++++++++++++++++++++++++ src/helper/streaming/text.test.ts | 35 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/helper/streaming/index.test.ts create mode 100644 src/helper/streaming/text.test.ts diff --git a/src/helper/streaming/index.test.ts b/src/helper/streaming/index.test.ts new file mode 100644 index 000000000..c834c7df6 --- /dev/null +++ b/src/helper/streaming/index.test.ts @@ -0,0 +1,28 @@ +import { Context } from '../../context' +import { HonoRequest } from '../../request' +import { stream } from '.' + +describe('Basic Streaming Helper', () => { + const req = new HonoRequest(new Request('http://localhost/')) + let c: Context + beforeEach(() => { + c = new Context(req) + }) + + it('Check SSE Response', async () => { + const res = stream(c, async (stream) => { + for (let i = 0; i < 3; i++) { + await stream.write(new Uint8Array([i])) + await stream.sleep(1) + } + }) + if (!res.body) { + throw new Error('Body is null') + } + const reader = res.body.getReader() + for (let i = 0; i < 3; i++) { + const { value } = await reader.read() + expect(value).toEqual(new Uint8Array([i])) + } + }) +}) diff --git a/src/helper/streaming/text.test.ts b/src/helper/streaming/text.test.ts new file mode 100644 index 000000000..a81584daf --- /dev/null +++ b/src/helper/streaming/text.test.ts @@ -0,0 +1,35 @@ +import { Context } from '../../context' +import { HonoRequest } from '../../request' +import { streamText } from '.' + +describe('Text Streaming Helper', () => { + const req = new HonoRequest(new Request('http://localhost/')) + let c: Context + beforeEach(() => { + c = new Context(req) + }) + + it('Check streamText Response', async () => { + const res = streamText(c, async (stream) => { + for (let i = 0; i < 3; i++) { + await stream.write(`${i}`) + await stream.sleep(1) + } + }) + + expect(res.status).toBe(200) + expect(res.headers.get('content-type')).toMatch(/^text\/plain/) + expect(res.headers.get('x-content-type-options')).toBe('nosniff') + expect(res.headers.get('transfer-encoding')).toBe('chunked') + + if (!res.body) { + throw new Error('Body is null') + } + const reader = res.body.getReader() + const decoder = new TextDecoder() + for (let i = 0; i < 3; i++) { + const { value } = await reader.read() + expect(decoder.decode(value)).toEqual(`${i}`) + } + }) +}) From e0864b9bfd775a2fc4b5b66d97b8a31dde3cb275 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:40:28 +0900 Subject: [PATCH 08/13] test: refactor `streamSSE` case for uniformity --- src/helper/streaming/sse.test.ts | 33 +++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/helper/streaming/sse.test.ts b/src/helper/streaming/sse.test.ts index e6c9ad157..a6dc9b3a4 100644 --- a/src/helper/streaming/sse.test.ts +++ b/src/helper/streaming/sse.test.ts @@ -1,23 +1,26 @@ -import { Hono } from '../../hono' +import { Context } from '../../context' +import { HonoRequest } from '../../request' import { streamSSE } from '.' -describe('SSE Streaming headers', () => { - it('Check SSE Response', async () => { - const app = new Hono() - app.get('/sse', async (c) => { - return streamSSE(c, async (stream) => { - let id = 0 - const maxIterations = 5 +describe('SSE Streaming helper', () => { + const req = new HonoRequest(new Request('http://localhost/')) + let c: Context + beforeEach(() => { + c = new Context(req) + }) + + it('Check streamSSE Response', async () => { + const res = streamSSE(c, async (stream) => { + let id = 0 + const maxIterations = 5 - while (id < maxIterations) { - const message = `Message\nIt is ${id}` - await stream.writeSSE({ data: message, event: 'time-update', id: String(id++) }) - await stream.sleep(100) - } - }) + while (id < maxIterations) { + const message = `Message\nIt is ${id}` + await stream.writeSSE({ data: message, event: 'time-update', id: String(id++) }) + await stream.sleep(100) + } }) - const res = await app.request('/sse') expect(res).not.toBeNull() expect(res.status).toBe(200) expect(res.headers.get('Transfer-Encoding')).toEqual('chunked') From 039e55389bf5f465d3fe1d86db5c4485d7c2bca2 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Sat, 23 Dec 2023 16:41:29 +0900 Subject: [PATCH 09/13] chore: denoify --- deno_dist/context.ts | 10 +++- deno_dist/helper/streaming/index.ts | 72 +++++++---------------------- deno_dist/helper/streaming/sse.ts | 60 ++++++++++++++++++++++++ deno_dist/helper/streaming/text.ts | 18 ++++++++ 4 files changed, 103 insertions(+), 57 deletions(-) create mode 100644 deno_dist/helper/streaming/sse.ts create mode 100644 deno_dist/helper/streaming/text.ts diff --git a/deno_dist/context.ts b/deno_dist/context.ts index 0605f0105..4c928dd7e 100644 --- a/deno_dist/context.ts +++ b/deno_dist/context.ts @@ -8,7 +8,7 @@ import type { StatusCode } from './utils/http-status.ts' import { StreamingApi } from './utils/stream.ts' import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types.ts' -type HeaderRecord = Record +export type HeaderRecord = Record type Data = string | ArrayBuffer | ReadableStream export interface ExecutionContext { @@ -83,7 +83,7 @@ type ContextOptions = { notFoundHandler?: NotFoundHandler } -const TEXT_PLAIN = 'text/plain; charset=UTF-8' +export const TEXT_PLAIN = 'text/plain; charset=UTF-8' export class Context< // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -375,6 +375,9 @@ export class Context< return this.newResponse(null, status) } + /** @deprecated + * Use `streamText()` in `hono/helper/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. + */ streamText = ( cb: (stream: StreamingApi) => Promise, arg?: StatusCode | ResponseInit, @@ -387,6 +390,9 @@ export class Context< return this.stream(cb, arg, headers) } + /** @deprecated + * Use `stream()` in `hono/helper/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. + */ stream = ( cb: (stream: StreamingApi) => Promise, arg?: StatusCode | ResponseInit, diff --git a/deno_dist/helper/streaming/index.ts b/deno_dist/helper/streaming/index.ts index 503516af3..f6ba06074 100644 --- a/deno_dist/helper/streaming/index.ts +++ b/deno_dist/helper/streaming/index.ts @@ -1,59 +1,21 @@ -import type { Context } from '../../context.ts' +import type { Context, HeaderRecord } from '../../context.ts' +import type { StatusCode } from '../../utils/http-status.ts' import { StreamingApi } from '../../utils/stream.ts' -interface SSEMessage { - data: string - event?: string - id?: string +export const stream = ( + c: Context, + cb: (stream: StreamingApi) => Promise, + arg?: StatusCode | ResponseInit, + headers?: HeaderRecord +): Response => { + const { readable, writable } = new TransformStream() + const stream = new StreamingApi(writable) + cb(stream).finally(() => stream.close()) + + return typeof arg === 'number' + ? c.newResponse(readable, arg, headers) + : c.newResponse(readable, arg) } -class SSEStreamingApi extends StreamingApi { - constructor(writable: WritableStream) { - super(writable) - } - - async writeSSE(message: SSEMessage) { - const data = message.data - .split('\n') - .map((line) => { - return `data: ${line}` - }) - .join('\n') - - const sseData = - [message.event && `event: ${message.event}`, data, message.id && `id: ${message.id}`] - .filter(Boolean) - .join('\n') + '\n\n' - - await this.write(sseData) - } -} - -const setSSEHeaders = (context: Context) => { - context.header('Transfer-Encoding', 'chunked') - context.header('Content-Type', 'text/event-stream') - context.header('Cache-Control', 'no-cache') - context.header('Connection', 'keep-alive') -} - -export const streamSSE = (c: Context, cb: (stream: SSEStreamingApi) => Promise) => { - return c.stream(async (originalStream: StreamingApi) => { - const { readable, writable } = new TransformStream() - const stream = new SSEStreamingApi(writable) - - originalStream.pipe(readable).catch((err) => { - console.error('Error in stream piping: ', err) - stream.close() - }) - - setSSEHeaders(c) - - try { - await cb(stream) - } catch (err) { - console.error('Error during streaming: ', err) - } finally { - await stream.close() - } - }) -} +export { streamSSE } from './sse.ts' +export { streamText } from './text.ts' diff --git a/deno_dist/helper/streaming/sse.ts b/deno_dist/helper/streaming/sse.ts new file mode 100644 index 000000000..a4e083a6b --- /dev/null +++ b/deno_dist/helper/streaming/sse.ts @@ -0,0 +1,60 @@ +import type { Context } from '../../context.ts' +import { StreamingApi } from '../../utils/stream.ts' +import { stream } from './index.ts' + +interface SSEMessage { + data: string + event?: string + id?: string +} + +class SSEStreamingApi extends StreamingApi { + constructor(writable: WritableStream) { + super(writable) + } + + async writeSSE(message: SSEMessage) { + const data = message.data + .split('\n') + .map((line) => { + return `data: ${line}` + }) + .join('\n') + + const sseData = + [message.event && `event: ${message.event}`, data, message.id && `id: ${message.id}`] + .filter(Boolean) + .join('\n') + '\n\n' + + await this.write(sseData) + } +} + +const setSSEHeaders = (context: Context) => { + context.header('Transfer-Encoding', 'chunked') + context.header('Content-Type', 'text/event-stream') + context.header('Cache-Control', 'no-cache') + context.header('Connection', 'keep-alive') +} + +export const streamSSE = (c: Context, cb: (stream: SSEStreamingApi) => Promise) => { + return stream(c, async (originalStream: StreamingApi) => { + const { readable, writable } = new TransformStream() + const stream = new SSEStreamingApi(writable) + + originalStream.pipe(readable).catch((err) => { + console.error('Error in stream piping: ', err) + stream.close() + }) + + setSSEHeaders(c) + + try { + await cb(stream) + } catch (err) { + console.error('Error during streaming: ', err) + } finally { + await stream.close() + } + }) +} diff --git a/deno_dist/helper/streaming/text.ts b/deno_dist/helper/streaming/text.ts new file mode 100644 index 000000000..563f67bb3 --- /dev/null +++ b/deno_dist/helper/streaming/text.ts @@ -0,0 +1,18 @@ +import type { Context, HeaderRecord } from '../../context.ts' +import { TEXT_PLAIN } from '../../context.ts' +import type { StatusCode } from '../../utils/http-status.ts' +import type { StreamingApi } from '../../utils/stream.ts' +import { stream } from './index.ts' + +export const streamText = ( + c: Context, + cb: (stream: StreamingApi) => Promise, + arg?: StatusCode | ResponseInit, + headers?: HeaderRecord +): Response => { + headers ??= {} + c.header('content-type', TEXT_PLAIN) + c.header('x-content-type-options', 'nosniff') + c.header('transfer-encoding', 'chunked') + return stream(c, cb, arg, headers) +} From 9f31d2cdc1656941cc0d1f62d0cf2556f4b6dc67 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Mon, 25 Dec 2023 02:44:35 +0000 Subject: [PATCH 10/13] fix: update jsdoc's deprecated description, simplify `c.stream` and `c.streamText` --- src/context.ts | 4 ++-- src/helper/streaming/index.ts | 15 +++------------ src/helper/streaming/text.ts | 13 +++---------- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/context.ts b/src/context.ts index 89c7dea21..d1049c570 100644 --- a/src/context.ts +++ b/src/context.ts @@ -376,7 +376,7 @@ export class Context< } /** @deprecated - * Use `streamText()` in `hono/helper/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. + * Use `streamText()` in `hono/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. */ streamText = ( cb: (stream: StreamingApi) => Promise, @@ -391,7 +391,7 @@ export class Context< } /** @deprecated - * Use `stream()` in `hono/helper/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. + * Use `stream()` in `hono/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. */ stream = ( cb: (stream: StreamingApi) => Promise, diff --git a/src/helper/streaming/index.ts b/src/helper/streaming/index.ts index df276cc07..65bee4322 100644 --- a/src/helper/streaming/index.ts +++ b/src/helper/streaming/index.ts @@ -1,20 +1,11 @@ -import type { Context, HeaderRecord } from '../../context' -import type { StatusCode } from '../../utils/http-status' +import type { Context } from '../../context' import { StreamingApi } from '../../utils/stream' -export const stream = ( - c: Context, - cb: (stream: StreamingApi) => Promise, - arg?: StatusCode | ResponseInit, - headers?: HeaderRecord -): Response => { +export const stream = (c: Context, cb: (stream: StreamingApi) => Promise): Response => { const { readable, writable } = new TransformStream() const stream = new StreamingApi(writable) cb(stream).finally(() => stream.close()) - - return typeof arg === 'number' - ? c.newResponse(readable, arg, headers) - : c.newResponse(readable, arg) + return c.newResponse(readable) } export { streamSSE } from './sse' diff --git a/src/helper/streaming/text.ts b/src/helper/streaming/text.ts index 45d592bcd..4ec63368a 100644 --- a/src/helper/streaming/text.ts +++ b/src/helper/streaming/text.ts @@ -1,18 +1,11 @@ -import type { Context, HeaderRecord } from '../../context' +import type { Context } from '../../context' import { TEXT_PLAIN } from '../../context' -import type { StatusCode } from '../../utils/http-status' import type { StreamingApi } from '../../utils/stream' import { stream } from '.' -export const streamText = ( - c: Context, - cb: (stream: StreamingApi) => Promise, - arg?: StatusCode | ResponseInit, - headers?: HeaderRecord -): Response => { - headers ??= {} +export const streamText = (c: Context, cb: (stream: StreamingApi) => Promise): Response => { c.header('content-type', TEXT_PLAIN) c.header('x-content-type-options', 'nosniff') c.header('transfer-encoding', 'chunked') - return stream(c, cb, arg, headers) + return stream(c, cb) } From 1b28081aa341241058b352d922e62051bbb209d9 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Mon, 25 Dec 2023 02:47:47 +0000 Subject: [PATCH 11/13] fix: match the header notation with that of `streamSSE --- src/helper/streaming/text.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helper/streaming/text.ts b/src/helper/streaming/text.ts index 4ec63368a..69a321a67 100644 --- a/src/helper/streaming/text.ts +++ b/src/helper/streaming/text.ts @@ -4,8 +4,8 @@ import type { StreamingApi } from '../../utils/stream' import { stream } from '.' export const streamText = (c: Context, cb: (stream: StreamingApi) => Promise): Response => { - c.header('content-type', TEXT_PLAIN) - c.header('x-content-type-options', 'nosniff') - c.header('transfer-encoding', 'chunked') + c.header('Content-Type', TEXT_PLAIN) + c.header('X-Content-Type-Options', 'nosniff') + c.header('Transfer-Encoding', 'chunked') return stream(c, cb) } From cb2f79e25066b5b817a1a4d0faf8a8c5cc501265 Mon Sep 17 00:00:00 2001 From: sor4chi Date: Mon, 25 Dec 2023 02:48:49 +0000 Subject: [PATCH 12/13] chore: denoify --- deno_dist/context.ts | 4 ++-- deno_dist/helper/streaming/index.ts | 15 +++------------ deno_dist/helper/streaming/text.ts | 19 ++++++------------- 3 files changed, 11 insertions(+), 27 deletions(-) diff --git a/deno_dist/context.ts b/deno_dist/context.ts index 4c928dd7e..7366c68e6 100644 --- a/deno_dist/context.ts +++ b/deno_dist/context.ts @@ -376,7 +376,7 @@ export class Context< } /** @deprecated - * Use `streamText()` in `hono/helper/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. + * Use `streamText()` in `hono/streaming` instead of `c.streamText()`. The `c.streamText()` will be removed in v4. */ streamText = ( cb: (stream: StreamingApi) => Promise, @@ -391,7 +391,7 @@ export class Context< } /** @deprecated - * Use `stream()` in `hono/helper/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. + * Use `stream()` in `hono/streaming` instead of `c.stream()`. The `c.stream()` will be removed in v4. */ stream = ( cb: (stream: StreamingApi) => Promise, diff --git a/deno_dist/helper/streaming/index.ts b/deno_dist/helper/streaming/index.ts index f6ba06074..9a829577b 100644 --- a/deno_dist/helper/streaming/index.ts +++ b/deno_dist/helper/streaming/index.ts @@ -1,20 +1,11 @@ -import type { Context, HeaderRecord } from '../../context.ts' -import type { StatusCode } from '../../utils/http-status.ts' +import type { Context } from '../../context.ts' import { StreamingApi } from '../../utils/stream.ts' -export const stream = ( - c: Context, - cb: (stream: StreamingApi) => Promise, - arg?: StatusCode | ResponseInit, - headers?: HeaderRecord -): Response => { +export const stream = (c: Context, cb: (stream: StreamingApi) => Promise): Response => { const { readable, writable } = new TransformStream() const stream = new StreamingApi(writable) cb(stream).finally(() => stream.close()) - - return typeof arg === 'number' - ? c.newResponse(readable, arg, headers) - : c.newResponse(readable, arg) + return c.newResponse(readable) } export { streamSSE } from './sse.ts' diff --git a/deno_dist/helper/streaming/text.ts b/deno_dist/helper/streaming/text.ts index 563f67bb3..7f6a978c3 100644 --- a/deno_dist/helper/streaming/text.ts +++ b/deno_dist/helper/streaming/text.ts @@ -1,18 +1,11 @@ -import type { Context, HeaderRecord } from '../../context.ts' +import type { Context } from '../../context.ts' import { TEXT_PLAIN } from '../../context.ts' -import type { StatusCode } from '../../utils/http-status.ts' import type { StreamingApi } from '../../utils/stream.ts' import { stream } from './index.ts' -export const streamText = ( - c: Context, - cb: (stream: StreamingApi) => Promise, - arg?: StatusCode | ResponseInit, - headers?: HeaderRecord -): Response => { - headers ??= {} - c.header('content-type', TEXT_PLAIN) - c.header('x-content-type-options', 'nosniff') - c.header('transfer-encoding', 'chunked') - return stream(c, cb, arg, headers) +export const streamText = (c: Context, cb: (stream: StreamingApi) => Promise): Response => { + c.header('Content-Type', TEXT_PLAIN) + c.header('X-Content-Type-Options', 'nosniff') + c.header('Transfer-Encoding', 'chunked') + return stream(c, cb) } From 132afe44b09537adcc16d28db30cfe0afda11f1c Mon Sep 17 00:00:00 2001 From: sor4chi Date: Mon, 25 Dec 2023 02:52:28 +0000 Subject: [PATCH 13/13] refactor: remove unnecesary export --- deno_dist/context.ts | 2 +- src/context.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deno_dist/context.ts b/deno_dist/context.ts index 7366c68e6..756cc5a64 100644 --- a/deno_dist/context.ts +++ b/deno_dist/context.ts @@ -8,7 +8,7 @@ import type { StatusCode } from './utils/http-status.ts' import { StreamingApi } from './utils/stream.ts' import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types.ts' -export type HeaderRecord = Record +type HeaderRecord = Record type Data = string | ArrayBuffer | ReadableStream export interface ExecutionContext { diff --git a/src/context.ts b/src/context.ts index d1049c570..88bd1f1f0 100644 --- a/src/context.ts +++ b/src/context.ts @@ -8,7 +8,7 @@ import type { StatusCode } from './utils/http-status' import { StreamingApi } from './utils/stream' import type { JSONValue, InterfaceToType, JSONParsed } from './utils/types' -export type HeaderRecord = Record +type HeaderRecord = Record type Data = string | ArrayBuffer | ReadableStream export interface ExecutionContext {