fix: handle context withing `render`

pull/18058/head
paoloricciuti 5 months ago
parent 8270a2fd55
commit a0b60cb137

@ -1,5 +1,7 @@
/** @import { ComponentContext } from '#client' */
import { boundary } from '../dom/blocks/boundary.js';
import { branch, effect_root } from '../reactivity/effects.js';
import { push, pop, component_context } from '../context.js';
import { push_renderer } from './state.js';
/**
@ -36,7 +38,7 @@ import { push_renderer } from './state.js';
* @template {object} [TTextNode=object]
* @template {object} [TComment=object]
* @param {Renderer<TFragment, TElement, TTextNode, TComment>} renderer
* @returns {Renderer<TFragment, TElement, TTextNode, TComment> & { render: (Component: any, options: { target: TFragment | TElement | TTextNode | TComment, props?: any }) => () => void }}
* @returns {Renderer<TFragment, TElement, TTextNode, TComment> & { render: (Component: any, options: { target: TFragment | TElement | TTextNode | TComment, props?: any, context?: Map<any, any> }) => () => void }}
*/
export function createRenderer(renderer) {
return {
@ -45,15 +47,19 @@ export function createRenderer(renderer) {
* @param {*} Component
* @param {*} options
*/
render(Component, { target, props }) {
render(Component, { target, props, context }) {
var cleanup = push_renderer(renderer);
const unmount = effect_root(() => {
var anchor = renderer.createComment('');
renderer.insert(target, anchor, null);
boundary(/** @type {*} */ (anchor), { pending: () => {} }, (anchor) => {
push({});
var ctx = /** @type {ComponentContext} */ (component_context);
if (context) ctx.c = context;
branch(() => {
Component(anchor, props);
});
pop();
});
});
cleanup();

@ -0,0 +1,6 @@
import { test } from '../../test';
export default test({
html: '<span>hello from render</span>',
context: new Map([['message', 'hello from render']])
});

@ -0,0 +1,7 @@
<script>
import { getContext } from 'svelte';
const message = getContext('message');
</script>
<span>{message}</span>

@ -0,0 +1,7 @@
<script>
import { getContext } from 'svelte';
const message = getContext('message');
</script>
<span>{message}</span>

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: '<div><span>hello from context</span></div>'
});

@ -0,0 +1,10 @@
<script>
import { setContext } from 'svelte';
import Child from './Child.svelte';
setContext('message', 'hello from context');
</script>
<div>
<Child />
</div>

@ -11,6 +11,7 @@ export interface CustomRendererTest extends BaseTest {
html?: string;
compileOptions?: Partial<CompileOptions>;
props?: Record<string, any>;
context?: Map<any, any>;
error?: string;
compile_error?: string;
runtime_error?: string;
@ -136,7 +137,8 @@ async function run_test(cwd: string, config: CustomRendererTest, compile_options
try {
unmount = renderer.render(mod.default, {
target,
props: config.props ?? {}
props: config.props ?? {},
context: config.context
});
} catch (err) {
if (config.error) {

Loading…
Cancel
Save