-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix solid recursion bug * Fix types * Remove debug code * Remove logging from e2e test
- Loading branch information
Showing
17 changed files
with
227 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import solid from '@astrojs/solid-js'; | ||
|
||
// https://astro.build/config | ||
export default defineConfig({ | ||
integrations: [solid()], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "@e2e/solid-recurse", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"@astrojs/solid-js": "workspace:*", | ||
"astro": "workspace:*" | ||
}, | ||
"devDependencies": { | ||
"solid-js": "^1.4.3" | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
packages/astro/e2e/fixtures/solid-recurse/src/components/Counter.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { createSignal } from 'solid-js'; | ||
|
||
export default function Counter(props) { | ||
const [count, setCount] = createSignal(0); | ||
const type = props.type; | ||
|
||
return ( | ||
<button | ||
id={props.id + '-' + type} | ||
data-type={type} | ||
ref={(el) => | ||
console.log( | ||
` ${type} ${type == el.dataset.type ? '==' : '!='} ${el.dataset.type}` | ||
) | ||
} | ||
onClick={() => { | ||
console.log('click'); | ||
setCount((p) => ++p); | ||
}} | ||
> | ||
{type}: {count()} | ||
</button> | ||
); | ||
} |
10 changes: 10 additions & 0 deletions
10
packages/astro/e2e/fixtures/solid-recurse/src/components/WrapperA.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Counter from './Counter'; | ||
|
||
export default function WrapperA(props) { | ||
return ( | ||
// removing the div avoids the error | ||
<div data-wrapper-a-root> | ||
<Counter id={props.id} type="A"></Counter> | ||
</div> | ||
); | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/astro/e2e/fixtures/solid-recurse/src/components/WrapperB.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Counter from './Counter'; | ||
|
||
export default function WrapperB(props) { | ||
return ( | ||
<div id={props.id}> | ||
{/* Reversing the order of these avoids the error: */} | ||
<div data-wrapper-children>{props.children}</div> | ||
<Counter id={props.id} type="B"></Counter> | ||
</div> | ||
); | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/astro/e2e/fixtures/solid-recurse/src/pages/index.astro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
--- | ||
import WrapperB from "../components/WrapperB.jsx"; | ||
import WrapperA from "../components/WrapperA.jsx"; | ||
--- | ||
|
||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width" /> | ||
</head> | ||
<body> | ||
<main> | ||
Case 1 | ||
<WrapperB id="case1" client:load> | ||
<WrapperA id="case1" /> | ||
</WrapperB> | ||
<br/> | ||
</main> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { expect } from '@playwright/test'; | ||
import { testFactory } from './test-utils.js'; | ||
|
||
const test = testFactory({ root: './fixtures/solid-recurse/' }); | ||
|
||
let devServer; | ||
|
||
test.beforeEach(async ({ astro }) => { | ||
devServer = await astro.startDevServer(); | ||
}); | ||
|
||
test.afterEach(async () => { | ||
await devServer.stop(); | ||
}); | ||
|
||
test.describe('Recursive elements with Solid', () => { | ||
test('Counter', async ({ astro, page }) => { | ||
await page.goto(astro.resolveUrl('/')); | ||
|
||
const wrapper = page.locator('#case1'); | ||
await expect(wrapper, 'component is visible').toBeVisible(); | ||
|
||
const increment = page.locator('#case1-B'); | ||
await expect(increment, 'initial count is 0').toHaveText('B: 0'); | ||
|
||
await increment.click(); | ||
await expect(increment, 'count is incremented').toHaveText('B: 1'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import type { RendererContext } from './types'; | ||
|
||
type Context = { | ||
id: string; | ||
c: number; | ||
} | ||
|
||
const contexts = new WeakMap<RendererContext['result'], Context>(); | ||
|
||
export function getContext(result: RendererContext['result']): Context { | ||
if(contexts.has(result)) { | ||
return contexts.get(result)!; | ||
} | ||
let ctx = { | ||
c: 0, | ||
get id() { | ||
return 's' + this.c.toString(); | ||
} | ||
}; | ||
contexts.set(result, ctx); | ||
return ctx; | ||
} | ||
|
||
export function incrementId(ctx: Context): string { | ||
let id = ctx.id; | ||
ctx.c++; | ||
return id; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import type { RendererContext } from './types'; | ||
import { renderToString, ssr, createComponent } from 'solid-js/web'; | ||
import { getContext, incrementId } from './context.js'; | ||
|
||
const slotName = (str: string) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); | ||
|
||
function check(this: RendererContext, Component: any, props: Record<string, any>, children: any) { | ||
if (typeof Component !== 'function') return false; | ||
const { html } = renderToStaticMarkup.call(this, Component, props, children); | ||
return typeof html === 'string'; | ||
} | ||
|
||
function renderToStaticMarkup(this: RendererContext, Component: any, props: Record<string, any>, { default: children, ...slotted }: any, metadata?: undefined | Record<string, any>) { | ||
const renderId = metadata?.hydrate ? incrementId(getContext(this.result)) : ''; | ||
|
||
const html = renderToString(() => { | ||
const slots: Record<string, any> = {}; | ||
for (const [key, value] of Object.entries(slotted)) { | ||
const name = slotName(key); | ||
slots[name] = ssr(`<astro-slot name="${name}">${value}</astro-slot>`); | ||
} | ||
// Note: create newProps to avoid mutating `props` before they are serialized | ||
const newProps = { | ||
...props, | ||
...slots, | ||
// In Solid SSR mode, `ssr` creates the expected structure for `children`. | ||
children: children != null ? ssr(`<astro-slot>${children}</astro-slot>`) : children, | ||
}; | ||
|
||
return createComponent(Component, newProps); | ||
}, { | ||
renderId | ||
}); | ||
return { | ||
attrs: { | ||
'data-solid-render-id': renderId | ||
}, | ||
html | ||
}; | ||
} | ||
|
||
export default { | ||
check, | ||
renderToStaticMarkup, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import type { SSRResult } from 'astro'; | ||
export type RendererContext = { | ||
result: SSRResult; | ||
}; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.