From c2cfeca490d844e49844246b4717abcb00d644af Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Tue, 19 Mar 2024 20:55:49 +0530 Subject: [PATCH 1/8] fix: use ReadableStream for response object if deno --- packages/astro/src/runtime/server/render/page.ts | 6 ++++-- packages/astro/src/runtime/server/render/util.ts | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index c27c11e6d3ac..e6852fa2a0ce 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -5,7 +5,7 @@ import type { AstroComponentFactory } from './index.js'; import { isAstroComponentFactory } from './astro/index.js'; import { renderToAsyncIterable, renderToReadableStream, renderToString } from './astro/render.js'; import { encoder } from './common.js'; -import { isNode } from './util.js'; +import { isNode, isDeno } from './util.js'; export async function renderPage( result: SSRResult, @@ -48,7 +48,9 @@ export async function renderPage( let body: BodyInit | Response; if (streaming) { - if (isNode) { + // isNode is true in Deno node-compat mode but response construction from + // async iterables is not supported, so we fallback to ReadableStream if isDeno is true. + if (isNode && !isDeno) { const nodeBody = await renderToAsyncIterable( result, componentFactory, diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 52149a0319f2..9a8bd2fcc55a 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -207,6 +207,7 @@ export function renderToBufferDestination(bufferRenderFunction: RenderFunction): export const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]'; +export const isDeno = typeof Deno !== 'undefined'; // We can get rid of this when Promise.withResolvers() is ready export type PromiseWithResolvers = { From f68081a83f5c5e6156bb7c22a3431e5480ae9abe Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Tue, 19 Mar 2024 21:14:15 +0530 Subject: [PATCH 2/8] fix build --- packages/astro/src/runtime/server/render/util.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 9a8bd2fcc55a..03d4599924a9 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -207,6 +207,7 @@ export function renderToBufferDestination(bufferRenderFunction: RenderFunction): export const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]'; +// @ts-expect-error: Deno is not part of the types. export const isDeno = typeof Deno !== 'undefined'; // We can get rid of this when Promise.withResolvers() is ready From 8bc4b74c94dc67df8aa78044805eeebd0d1362b7 Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Tue, 19 Mar 2024 21:22:29 +0530 Subject: [PATCH 3/8] update co-author From a6e6e22e9e7c28e9514b41f8e80c9050d1e3207d Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Tue, 19 Mar 2024 21:22:48 +0530 Subject: [PATCH 4/8] update co-author Co-authored-by: Divy Srivastava From 12a80065325769493e5be462e69027cdbd225fbc Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Wed, 20 Mar 2024 08:59:30 +0530 Subject: [PATCH 5/8] use platform agnostic feature test --- packages/astro/src/runtime/server/render/page.ts | 6 ++---- packages/astro/src/runtime/server/render/util.ts | 15 +++++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index e6852fa2a0ce..8c92fd91f219 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -5,7 +5,7 @@ import type { AstroComponentFactory } from './index.js'; import { isAstroComponentFactory } from './astro/index.js'; import { renderToAsyncIterable, renderToReadableStream, renderToString } from './astro/render.js'; import { encoder } from './common.js'; -import { isNode, isDeno } from './util.js'; +import { supportsResponseBodyAsyncIterator } from './util.js'; export async function renderPage( result: SSRResult, @@ -48,9 +48,7 @@ export async function renderPage( let body: BodyInit | Response; if (streaming) { - // isNode is true in Deno node-compat mode but response construction from - // async iterables is not supported, so we fallback to ReadableStream if isDeno is true. - if (isNode && !isDeno) { + if (supportsResponseBodyAsyncIterator) { const nodeBody = await renderToAsyncIterable( result, componentFactory, diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 03d4599924a9..373ffada637b 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -205,10 +205,17 @@ export function renderToBufferDestination(bufferRenderFunction: RenderFunction): }; } -export const isNode = - typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]'; -// @ts-expect-error: Deno is not part of the types. -export const isDeno = typeof Deno !== 'undefined'; +export const supportsResponseBodyAsyncIterator = (() => { + let supported = false; + new Response({ + // @ts-expect-error: Response types don't expect the property. + get [Symbol.asyncIterator]() { + supported = true; + return undefined; + }, + }); + return supported; +})(); // We can get rid of this when Promise.withResolvers() is ready export type PromiseWithResolvers = { From e98cbf9c3dc3c39341f82f153321fd4502fc72b1 Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Thu, 21 Mar 2024 08:57:25 +0530 Subject: [PATCH 6/8] changeset --- .changeset/cool-bulldogs-change.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cool-bulldogs-change.md diff --git a/.changeset/cool-bulldogs-change.md b/.changeset/cool-bulldogs-change.md new file mode 100644 index 000000000000..ac3b122e1e09 --- /dev/null +++ b/.changeset/cool-bulldogs-change.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Use ReadableStream if asyncIterator is not supported in Response construction. This patch enables astro node integration to work in Deno. From 0200f10f01f00ae2fb316119c5499d28231c5ace Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Fri, 22 Mar 2024 09:35:04 +0530 Subject: [PATCH 7/8] Revert "use platform agnostic feature test" This reverts commit 12a80065325769493e5be462e69027cdbd225fbc. --- packages/astro/src/runtime/server/render/page.ts | 6 ++++-- packages/astro/src/runtime/server/render/util.ts | 15 ++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/astro/src/runtime/server/render/page.ts b/packages/astro/src/runtime/server/render/page.ts index 8c92fd91f219..e6852fa2a0ce 100644 --- a/packages/astro/src/runtime/server/render/page.ts +++ b/packages/astro/src/runtime/server/render/page.ts @@ -5,7 +5,7 @@ import type { AstroComponentFactory } from './index.js'; import { isAstroComponentFactory } from './astro/index.js'; import { renderToAsyncIterable, renderToReadableStream, renderToString } from './astro/render.js'; import { encoder } from './common.js'; -import { supportsResponseBodyAsyncIterator } from './util.js'; +import { isNode, isDeno } from './util.js'; export async function renderPage( result: SSRResult, @@ -48,7 +48,9 @@ export async function renderPage( let body: BodyInit | Response; if (streaming) { - if (supportsResponseBodyAsyncIterator) { + // isNode is true in Deno node-compat mode but response construction from + // async iterables is not supported, so we fallback to ReadableStream if isDeno is true. + if (isNode && !isDeno) { const nodeBody = await renderToAsyncIterable( result, componentFactory, diff --git a/packages/astro/src/runtime/server/render/util.ts b/packages/astro/src/runtime/server/render/util.ts index 150b176c519c..61caff6cc6b0 100644 --- a/packages/astro/src/runtime/server/render/util.ts +++ b/packages/astro/src/runtime/server/render/util.ts @@ -205,17 +205,10 @@ export function renderToBufferDestination(bufferRenderFunction: RenderFunction): }; } -export const supportsResponseBodyAsyncIterator = (() => { - let supported = false; - new Response({ - // @ts-expect-error: Response types don't expect the property. - get [Symbol.asyncIterator]() { - supported = true; - return undefined; - }, - }); - return supported; -})(); +export const isNode = + typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]'; +// @ts-expect-error: Deno is not part of the types. +export const isDeno = typeof Deno !== 'undefined'; // We can get rid of this when Promise.withResolvers() is ready export type PromiseWithResolvers = { From d22c8771edcfd66a6be152c9100a06d843ef5822 Mon Sep 17 00:00:00 2001 From: Satya Rohith Date: Fri, 22 Mar 2024 09:45:11 +0530 Subject: [PATCH 8/8] update changeset --- .changeset/cool-bulldogs-change.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/cool-bulldogs-change.md b/.changeset/cool-bulldogs-change.md index ac3b122e1e09..fce9c1a2119c 100644 --- a/.changeset/cool-bulldogs-change.md +++ b/.changeset/cool-bulldogs-change.md @@ -2,4 +2,6 @@ "astro": patch --- -Use ReadableStream if asyncIterator is not supported in Response construction. This patch enables astro node integration to work in Deno. +This patch allows astro to run in node-compat mode in Deno. Deno doesn't support +construction of response from async iterables in node-compat mode so we need to +use ReadableStream.