From 93c7a6380ddd1d9f5f3538a2dfb2e54d6d96f3df Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Mon, 15 Jul 2024 17:39:51 +0100 Subject: [PATCH 01/14] Fix issue where rendered is a promise I want to test this in my project to see if this change fixes it. All being well, I'll then add a test here and submit it for review --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 9dec64ab..743f25aa 100644 --- a/src/index.js +++ b/src/index.js @@ -109,7 +109,7 @@ export async function renderToStringAsync(vnode, context) { parent[CHILDREN] = [vnode]; try { - const rendered = _renderToString( + const rendered = await _renderToString( vnode, context || EMPTY_OBJ, false, From b2287e2729a44227956b3333514989f5492b462b Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Mon, 15 Jul 2024 18:36:09 +0100 Subject: [PATCH 02/14] Different syntax, but more success I'm unclear why the previous didn't seem to work for me --- src/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 743f25aa..45d6ba67 100644 --- a/src/index.js +++ b/src/index.js @@ -109,7 +109,7 @@ export async function renderToStringAsync(vnode, context) { parent[CHILDREN] = [vnode]; try { - const rendered = await _renderToString( + let rendered = _renderToString( vnode, context || EMPTY_OBJ, false, @@ -119,6 +119,10 @@ export async function renderToStringAsync(vnode, context) { undefined ); + if (rendered instanceof Promise) { + rendered = [rendered]; + } + if (Array.isArray(rendered)) { let count = 0; let resolved = rendered; From 6dec254a46c7e8ec3f522daa8e3e93edad809639 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Mon, 15 Jul 2024 19:51:31 +0100 Subject: [PATCH 03/14] Attempt to write a test for the case based on my app So far no luck actually reproducing the issue. I will take a different tact and remove code from my app until the issue goes away, to figure out what causes the behaviour. --- package-lock.json | 76 +++++++++++++++++++++++++++- package.json | 4 +- src/index.js | 6 +-- test/compat/async.test.jsx | 101 +++++++++++++++++++++++++++++++------ 4 files changed, 166 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index c645b168..c7c2d097 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "preact-render-to-string", - "version": "6.5.2", + "version": "6.5.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "preact-render-to-string", - "version": "6.5.2", + "version": "6.5.5", "license": "MIT", "devDependencies": { "@babel/plugin-transform-react-jsx": "^7.12.12", @@ -14,6 +14,8 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", + "@preact/signals": "^1.3.0", + "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", "chai": "^4.2.0", @@ -37,6 +39,20 @@ "preact": ">=10" } }, + "node_modules/@0no-co/graphql.web": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.7.tgz", + "integrity": "sha512-E3Qku4mTzdrlwVWGPxklDnME5ANrEGetvYw4i2GCRlppWXXE4QD66j7pwb8HelZwS6LnqEChhrSOGCXpbiu6MQ==", + "dev": true, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, "node_modules/@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", @@ -1992,6 +2008,32 @@ "node": ">= 8" } }, + "node_modules/@preact/signals": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.0.tgz", + "integrity": "sha512-EOMeg42SlLS72dhoq6Vjq08havnLseWmPQ8A0YsgIAqMgWgx7V1a39+Pxo6i7SY5NwJtH4849JogFq3M67AzWg==", + "dev": true, + "dependencies": { + "@preact/signals-core": "^1.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "preact": "10.x" + } + }, + "node_modules/@preact/signals-core": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.7.0.tgz", + "integrity": "sha512-bEZLgmJGSBVP5PUPDowhPW3bVdMmp9Tr5OEl+SQK+8Tv9T7UsIfyN905cfkmmeqw8z4xp8T6zrl4M1uj9+HAfg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/@rollup/plugin-alias": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.1.tgz", @@ -2264,6 +2306,30 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, + "node_modules/@urql/core": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.0.4.tgz", + "integrity": "sha512-gl86J6B6gWXvvkx5omZ+CaGiPQ0chCUGM0jBsm0zTtkDQPRqufv0NSUN6sp2JhGGtTOB0NR6Pd+w7XAVGGyUOA==", + "dev": true, + "dependencies": { + "@0no-co/graphql.web": "^1.0.5", + "wonka": "^6.3.2" + } + }, + "node_modules/@urql/preact": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@urql/preact/-/preact-4.1.0.tgz", + "integrity": "sha512-mxjzc/MrTalRFGJ9oVb6fMfnNo70PUDNQYLyXzx3aC1mvQcjADCQeYOVVCYmzPBX3tvs4mS5QfJy83wD2UT20g==", + "dev": true, + "dependencies": { + "@urql/core": "^5.0.0", + "wonka": "^6.3.2" + }, + "peerDependencies": { + "@urql/core": "^5.0.0", + "preact": ">= 10.0.0" + } + }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -13392,6 +13458,12 @@ "node": ">=4" } }, + "node_modules/wonka": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", + "integrity": "sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==", + "dev": true + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 784b3a7d..9b73ebfe 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,8 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", + "@preact/signals": "^1.3.0", + "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", "chai": "^4.2.0", @@ -170,4 +172,4 @@ "publishConfig": { "provenance": true } -} \ No newline at end of file +} diff --git a/src/index.js b/src/index.js index 45d6ba67..1c00c75d 100644 --- a/src/index.js +++ b/src/index.js @@ -119,9 +119,9 @@ export async function renderToStringAsync(vnode, context) { undefined ); - if (rendered instanceof Promise) { - rendered = [rendered]; - } + // if (rendered instanceof Promise) { + // rendered = [rendered]; + // } if (Array.isArray(rendered)) { let count = 0; diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 8b50c001..38d7513d 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,8 +1,12 @@ import { renderToStringAsync } from '../../src/index.js'; -import { h } from 'preact'; +import { h, createContext, Fragment } from 'preact'; import { Suspense, useId } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; +import * as urql from '@urql/preact'; +import { Deferred } from '../../src/lib/util.js'; +import { signal } from '@preact/signals'; +import { useContext } from 'preact/hooks'; describe('Async renderToString', () => { it('should render JSX after a suspense boundary', async () => { @@ -26,10 +30,14 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspended components', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); const promise = renderToStringAsync(
    @@ -56,10 +64,14 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspense boundaries', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); const promise = renderToStringAsync(
      @@ -88,12 +100,18 @@ describe('Async renderToString', () => { }); it('should render JSX with multiple suspended direct children within a single suspense boundary', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); - const { Suspender: SuspenderThree, suspended: suspendedThree } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); + const { + Suspender: SuspenderThree, + suspended: suspendedThree + } = createSuspender(); const promise = renderToStringAsync(
        @@ -175,4 +193,57 @@ describe('Async renderToString', () => { const rendered = await promise; expect(rendered).to.equal('

        ok

        '); }); + + it.only('should render JSX after a urql component', async () => { + const deferred = new Deferred(); + const client = urql.createClient({ + url: 'http://localhost:1234', + exchanges: [urql.cacheExchange, urql.fetchExchange], + suspense: true, + fetch: () => + deferred.promise.then(() => new Response('{ "data": { "foo": 4 } }')) + // fetch: (args) => Promise.resolve(new Response('{ "data": { "foo": 4 } }')) + }); + const Context = createContext({ + store: signal(null) + }); + + const ContextProvider = ({ children }) => ( + + {children} + + ); + const Fetcher = ({ children }) => { + const store = useContext(Context).store; + + const [{ data }] = urql.useQuery({ + query: 'query{ foo }' + }); + store.foo = data.foo; + return {children}; + }; + + const Reactor = () => { + const store = useContext(Context).store; + return
        {store.foo}
        ; + }; + + const promise = renderToStringAsync( + + + + + + + + + ); + + deferred.resolve(); + const rendered = await promise; + + const expected = `
        4
        4
        `; + + expect(rendered).to.equal(expected); + }); }); From 57958309528e5db5290bcd06a322d22d543e7fe2 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 11:41:08 +0100 Subject: [PATCH 04/14] Add test that tests behaviour --- test/compat/async.test.jsx | 65 ++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 38d7513d..9bb12919 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,12 +1,9 @@ import { renderToStringAsync } from '../../src/index.js'; import { h, createContext, Fragment } from 'preact'; -import { Suspense, useId } from 'preact/compat'; +import { Suspense, useId, lazy } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; import * as urql from '@urql/preact'; -import { Deferred } from '../../src/lib/util.js'; -import { signal } from '@preact/signals'; -import { useContext } from 'preact/hooks'; describe('Async renderToString', () => { it('should render JSX after a suspense boundary', async () => { @@ -195,54 +192,54 @@ describe('Async renderToString', () => { }); it.only('should render JSX after a urql component', async () => { - const deferred = new Deferred(); const client = urql.createClient({ url: 'http://localhost:1234', exchanges: [urql.cacheExchange, urql.fetchExchange], suspense: true, - fetch: () => - deferred.promise.then(() => new Response('{ "data": { "foo": 4 } }')) - // fetch: (args) => Promise.resolve(new Response('{ "data": { "foo": 4 } }')) - }); - const Context = createContext({ - store: signal(null) + fetch: (args) => + Promise.resolve( + new Response('{ "data": { "foo": 4 } }', { + headers: { 'Content-Type': 'application/json' } + }) + ) }); - const ContextProvider = ({ children }) => ( - - {children} - - ); const Fetcher = ({ children }) => { - const store = useContext(Context).store; - - const [{ data }] = urql.useQuery({ - query: 'query{ foo }' - }); - store.foo = data.foo; + urql.useQuery({ query: 'query{ foo }' }); return {children}; }; - const Reactor = () => { - const store = useContext(Context).store; - return
        {store.foo}
        ; - }; + const ThemeContext = createContext('light'); + + const LazyComponent = lazy(async () => { + await new Promise((r) => setTimeout(r, 200)); + + return function ImportedComponent() { + return ( + +
        2
        +
        + ); + }; + }); + + const LoadableTheme = ({}) => ( + + + + ); const promise = renderToStringAsync( - - - - - - + + + ); - deferred.resolve(); const rendered = await promise; - const expected = `
        4
        4
        `; + const expected = `
        2
        `; expect(rendered).to.equal(expected); }); From d882836faf25b23c6c7f1b3d41eaa1c4fd5f40d1 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 11:49:21 +0100 Subject: [PATCH 05/14] Further simplify test case --- test/compat/async.test.jsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 9bb12919..5e680cda 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,5 +1,5 @@ import { renderToStringAsync } from '../../src/index.js'; -import { h, createContext, Fragment } from 'preact'; +import { h, Fragment } from 'preact'; import { Suspense, useId, lazy } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; @@ -209,21 +209,15 @@ describe('Async renderToString', () => { return {children}; }; - const ThemeContext = createContext('light'); - const LazyComponent = lazy(async () => { - await new Promise((r) => setTimeout(r, 200)); + await new Promise((r) => setTimeout(r, 0)); return function ImportedComponent() { - return ( - -
        2
        -
        - ); + return
        2
        ; }; }); - const LoadableTheme = ({}) => ( + const LoadableComponent = ({}) => ( @@ -232,7 +226,7 @@ describe('Async renderToString', () => { const promise = renderToStringAsync( - + ); From 61a31f1d3ed46a2264afcfac605555cba0754ba0 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 11:51:01 +0100 Subject: [PATCH 06/14] Further simplify test case --- test/compat/async.test.jsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 5e680cda..4faef09a 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -209,13 +209,12 @@ describe('Async renderToString', () => { return {children}; }; - const LazyComponent = lazy(async () => { - await new Promise((r) => setTimeout(r, 0)); - - return function ImportedComponent() { - return
        2
        ; - }; - }); + const LazyComponent = lazy( + async () => + function ImportedComponent() { + return
        2
        ; + } + ); const LoadableComponent = ({}) => ( From fdc2b1a774a58b6358401bdd13c370b70af452cd Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 13:22:29 +0100 Subject: [PATCH 07/14] Create the test I want --- package-lock.json | 27 --------------------------- package.json | 1 - src/index.js | 6 +----- test/compat/async.test.jsx | 12 ++++-------- 4 files changed, 5 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7c2d097..eadfb853 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", - "@preact/signals": "^1.3.0", "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", @@ -2008,32 +2007,6 @@ "node": ">= 8" } }, - "node_modules/@preact/signals": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.0.tgz", - "integrity": "sha512-EOMeg42SlLS72dhoq6Vjq08havnLseWmPQ8A0YsgIAqMgWgx7V1a39+Pxo6i7SY5NwJtH4849JogFq3M67AzWg==", - "dev": true, - "dependencies": { - "@preact/signals-core": "^1.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - }, - "peerDependencies": { - "preact": "10.x" - } - }, - "node_modules/@preact/signals-core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.7.0.tgz", - "integrity": "sha512-bEZLgmJGSBVP5PUPDowhPW3bVdMmp9Tr5OEl+SQK+8Tv9T7UsIfyN905cfkmmeqw8z4xp8T6zrl4M1uj9+HAfg==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/@rollup/plugin-alias": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.1.tgz", diff --git a/package.json b/package.json index 9b73ebfe..275158a8 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,6 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", - "@preact/signals": "^1.3.0", "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", diff --git a/src/index.js b/src/index.js index 1c00c75d..743f25aa 100644 --- a/src/index.js +++ b/src/index.js @@ -109,7 +109,7 @@ export async function renderToStringAsync(vnode, context) { parent[CHILDREN] = [vnode]; try { - let rendered = _renderToString( + const rendered = await _renderToString( vnode, context || EMPTY_OBJ, false, @@ -119,10 +119,6 @@ export async function renderToStringAsync(vnode, context) { undefined ); - // if (rendered instanceof Promise) { - // rendered = [rendered]; - // } - if (Array.isArray(rendered)) { let count = 0; let resolved = rendered; diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 4faef09a..04356b82 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -191,12 +191,12 @@ describe('Async renderToString', () => { expect(rendered).to.equal('

        ok

        '); }); - it.only('should render JSX after a urql component', async () => { + it('should render JSX after a urql component', async () => { const client = urql.createClient({ url: 'http://localhost:1234', exchanges: [urql.cacheExchange, urql.fetchExchange], suspense: true, - fetch: (args) => + fetch: () => Promise.resolve( new Response('{ "data": { "foo": 4 } }', { headers: { 'Content-Type': 'application/json' } @@ -222,7 +222,7 @@ describe('Async renderToString', () => {
        ); - const promise = renderToStringAsync( + const rendered = await renderToStringAsync( @@ -230,10 +230,6 @@ describe('Async renderToString', () => { ); - const rendered = await promise; - - const expected = `
        2
        `; - - expect(rendered).to.equal(expected); + expect(rendered).to.equal(`
        2
        `); }); }); From 0f7f1d07a031983e58fa4544e366d21b7894b585 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 13:34:19 +0100 Subject: [PATCH 08/14] Revert unrelated change --- test/compat/async.test.jsx | 47 +++++++++++++------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 04356b82..3a3ef068 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,9 +1,8 @@ import { renderToStringAsync } from '../../src/index.js'; -import { h, Fragment } from 'preact'; -import { Suspense, useId, lazy } from 'preact/compat'; +import { h } from 'preact'; +import { Suspense, useId } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; -import * as urql from '@urql/preact'; describe('Async renderToString', () => { it('should render JSX after a suspense boundary', async () => { @@ -27,14 +26,10 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspended components', async () => { - const { - Suspender: SuspenderOne, - suspended: suspendedOne - } = createSuspender(); - const { - Suspender: SuspenderTwo, - suspended: suspendedTwo - } = createSuspender(); + const { Suspender: SuspenderOne, suspended: suspendedOne } = + createSuspender(); + const { Suspender: SuspenderTwo, suspended: suspendedTwo } = + createSuspender(); const promise = renderToStringAsync(
          @@ -61,14 +56,10 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspense boundaries', async () => { - const { - Suspender: SuspenderOne, - suspended: suspendedOne - } = createSuspender(); - const { - Suspender: SuspenderTwo, - suspended: suspendedTwo - } = createSuspender(); + const { Suspender: SuspenderOne, suspended: suspendedOne } = + createSuspender(); + const { Suspender: SuspenderTwo, suspended: suspendedTwo } = + createSuspender(); const promise = renderToStringAsync(
            @@ -97,18 +88,12 @@ describe('Async renderToString', () => { }); it('should render JSX with multiple suspended direct children within a single suspense boundary', async () => { - const { - Suspender: SuspenderOne, - suspended: suspendedOne - } = createSuspender(); - const { - Suspender: SuspenderTwo, - suspended: suspendedTwo - } = createSuspender(); - const { - Suspender: SuspenderThree, - suspended: suspendedThree - } = createSuspender(); + const { Suspender: SuspenderOne, suspended: suspendedOne } = + createSuspender(); + const { Suspender: SuspenderTwo, suspended: suspendedTwo } = + createSuspender(); + const { Suspender: SuspenderThree, suspended: suspendedThree } = + createSuspender(); const promise = renderToStringAsync(
              From f1614477a1e6b15fa0b97bc7086e2d5761b12119 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 13:39:16 +0100 Subject: [PATCH 09/14] Add changeset --- .changeset/famous-experts-decide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/famous-experts-decide.md diff --git a/.changeset/famous-experts-decide.md b/.changeset/famous-experts-decide.md new file mode 100644 index 00000000..476006ab --- /dev/null +++ b/.changeset/famous-experts-decide.md @@ -0,0 +1,5 @@ +--- +'preact-render-to-string': patch +--- + +Fix issue where preactRenderToString returns a promise of a promise From 58d7e017500880400f459bf322fb2fa8488c7f43 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 13:58:41 +0100 Subject: [PATCH 10/14] Add missing imports --- test/compat/async.test.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 3a3ef068..93c3f2ba 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,8 +1,9 @@ import { renderToStringAsync } from '../../src/index.js'; -import { h } from 'preact'; -import { Suspense, useId } from 'preact/compat'; +import { h, Fragment } from 'preact'; +import { Suspense, useId, lazy } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; +import * as urql from '@urql/preact'; describe('Async renderToString', () => { it('should render JSX after a suspense boundary', async () => { From 8759b730bd95cdd744e146ca104855c088b6ed5c Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 15:29:46 +0100 Subject: [PATCH 11/14] Reproduce without useClient But I still need the provider --- test/compat/async.test.jsx | 51 ++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 93c3f2ba..b9eaa727 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -27,10 +27,14 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspended components', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); const promise = renderToStringAsync(
                @@ -57,10 +61,14 @@ describe('Async renderToString', () => { }); it('should render JSX with nested suspense boundaries', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); const promise = renderToStringAsync(
                  @@ -89,12 +97,18 @@ describe('Async renderToString', () => { }); it('should render JSX with multiple suspended direct children within a single suspense boundary', async () => { - const { Suspender: SuspenderOne, suspended: suspendedOne } = - createSuspender(); - const { Suspender: SuspenderTwo, suspended: suspendedTwo } = - createSuspender(); - const { Suspender: SuspenderThree, suspended: suspendedThree } = - createSuspender(); + const { + Suspender: SuspenderOne, + suspended: suspendedOne + } = createSuspender(); + const { + Suspender: SuspenderTwo, + suspended: suspendedTwo + } = createSuspender(); + const { + Suspender: SuspenderThree, + suspended: suspendedThree + } = createSuspender(); const promise = renderToStringAsync(
                    @@ -177,7 +191,7 @@ describe('Async renderToString', () => { expect(rendered).to.equal('

                    ok

                    '); }); - it('should render JSX after a urql component', async () => { + it.only('should render JSX after a urql component', async () => { const client = urql.createClient({ url: 'http://localhost:1234', exchanges: [urql.cacheExchange, urql.fetchExchange], @@ -190,8 +204,13 @@ describe('Async renderToString', () => { ) }); + let c = 0; + const Fetcher = ({ children }) => { - urql.useQuery({ query: 'query{ foo }' }); + c++; + if (c === 1) { + throw Promise.resolve(); + } return {children}; }; From 3ba55d8a0e0c0bc7964f67b62b173ba74d1873f4 Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 16:59:37 +0100 Subject: [PATCH 12/14] Avoid using urql --- package-lock.json | 49 ++------------------------------------ package.json | 3 +-- test/compat/async.test.jsx | 21 ++++------------ 3 files changed, 8 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index eadfb853..c645b168 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "preact-render-to-string", - "version": "6.5.5", + "version": "6.5.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "preact-render-to-string", - "version": "6.5.5", + "version": "6.5.2", "license": "MIT", "devDependencies": { "@babel/plugin-transform-react-jsx": "^7.12.12", @@ -14,7 +14,6 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", - "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", "chai": "^4.2.0", @@ -38,20 +37,6 @@ "preact": ">=10" } }, - "node_modules/@0no-co/graphql.web": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.0.7.tgz", - "integrity": "sha512-E3Qku4mTzdrlwVWGPxklDnME5ANrEGetvYw4i2GCRlppWXXE4QD66j7pwb8HelZwS6LnqEChhrSOGCXpbiu6MQ==", - "dev": true, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" - }, - "peerDependenciesMeta": { - "graphql": { - "optional": true - } - } - }, "node_modules/@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", @@ -2279,30 +2264,6 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "node_modules/@urql/core": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@urql/core/-/core-5.0.4.tgz", - "integrity": "sha512-gl86J6B6gWXvvkx5omZ+CaGiPQ0chCUGM0jBsm0zTtkDQPRqufv0NSUN6sp2JhGGtTOB0NR6Pd+w7XAVGGyUOA==", - "dev": true, - "dependencies": { - "@0no-co/graphql.web": "^1.0.5", - "wonka": "^6.3.2" - } - }, - "node_modules/@urql/preact": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@urql/preact/-/preact-4.1.0.tgz", - "integrity": "sha512-mxjzc/MrTalRFGJ9oVb6fMfnNo70PUDNQYLyXzx3aC1mvQcjADCQeYOVVCYmzPBX3tvs4mS5QfJy83wD2UT20g==", - "dev": true, - "dependencies": { - "@urql/core": "^5.0.0", - "wonka": "^6.3.2" - }, - "peerDependencies": { - "@urql/core": "^5.0.0", - "preact": ">= 10.0.0" - } - }, "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", @@ -13431,12 +13392,6 @@ "node": ">=4" } }, - "node_modules/wonka": { - "version": "6.3.4", - "resolved": "https://registry.npmjs.org/wonka/-/wonka-6.3.4.tgz", - "integrity": "sha512-CjpbqNtBGNAeyNS/9W6q3kSkKE52+FjIj7AkFlLr11s/VWGUu6a2CdYSdGxocIhIVjaW/zchesBQUKPVU69Cqg==", - "dev": true - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 275158a8..784b3a7d 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,6 @@ "@babel/register": "^7.12.10", "@changesets/changelog-github": "^0.4.1", "@changesets/cli": "^2.18.0", - "@urql/preact": "^4.1.0", "baseline-rts": "npm:preact-render-to-string@latest", "benchmarkjs-pretty": "^2.0.1", "chai": "^4.2.0", @@ -171,4 +170,4 @@ "publishConfig": { "provenance": true } -} +} \ No newline at end of file diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index b9eaa727..10f9a5a4 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -1,9 +1,8 @@ import { renderToStringAsync } from '../../src/index.js'; import { h, Fragment } from 'preact'; -import { Suspense, useId, lazy } from 'preact/compat'; +import { Suspense, useId, lazy, createContext } from 'preact/compat'; import { expect } from 'chai'; import { createSuspender } from '../utils.jsx'; -import * as urql from '@urql/preact'; describe('Async renderToString', () => { it('should render JSX after a suspense boundary', async () => { @@ -191,18 +190,8 @@ describe('Async renderToString', () => { expect(rendered).to.equal('

                    ok

                    '); }); - it.only('should render JSX after a urql component', async () => { - const client = urql.createClient({ - url: 'http://localhost:1234', - exchanges: [urql.cacheExchange, urql.fetchExchange], - suspense: true, - fetch: () => - Promise.resolve( - new Response('{ "data": { "foo": 4 } }', { - headers: { 'Content-Type': 'application/json' } - }) - ) - }); + it('should render JSX after a urql component', async () => { + const ThemeContext = createContext('light'); let c = 0; @@ -228,11 +217,11 @@ describe('Async renderToString', () => { ); const rendered = await renderToStringAsync( - + - + ); expect(rendered).to.equal(`
                    2
                    `); From 0967404310c13b1ead774aecf559e6970c10ddbe Mon Sep 17 00:00:00 2001 From: Chris Couzens Date: Wed, 17 Jul 2024 17:04:32 +0100 Subject: [PATCH 13/14] Better description --- test/compat/async.test.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 10f9a5a4..9fa89556 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -190,8 +190,8 @@ describe('Async renderToString', () => { expect(rendered).to.equal('

                    ok

                    '); }); - it('should render JSX after a urql component', async () => { - const ThemeContext = createContext('light'); + it('should work with setup comparable to URQL containing a lazy loaded component', async () => { + const Context = createContext(); let c = 0; @@ -217,11 +217,11 @@ describe('Async renderToString', () => { ); const rendered = await renderToStringAsync( - + - + ); expect(rendered).to.equal(`
                    2
                    `); From 7bd6b2901ebb2539e360002cf23ac8c441b21530 Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Wed, 17 Jul 2024 19:01:17 +0200 Subject: [PATCH 14/14] Update test/compat/async.test.jsx --- test/compat/async.test.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compat/async.test.jsx b/test/compat/async.test.jsx index 9fa89556..968c12b1 100644 --- a/test/compat/async.test.jsx +++ b/test/compat/async.test.jsx @@ -190,7 +190,7 @@ describe('Async renderToString', () => { expect(rendered).to.equal('

                    ok

                    '); }); - it('should work with setup comparable to URQL containing a lazy loaded component', async () => { + it('should work with an in-render suspension', async () => { const Context = createContext(); let c = 0;