File tree Expand file tree Collapse file tree 6 files changed +64
-1
lines changed
documentation/docs/98-reference/.generated
tests/runtime-runes/samples/set-context-after-mount Expand file tree Collapse file tree 6 files changed +64
-1
lines changed Original file line number Diff line number Diff line change @@ -110,6 +110,12 @@ Rest element properties of `$props()` such as `%property%` are readonly
110110The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
111111```
112112
113+ ### set_context_after_init
114+
115+ ```
116+ `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
117+ ```
118+
113119### state_descriptors_fixed
114120
115121```
Original file line number Diff line number Diff line change @@ -72,6 +72,10 @@ See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-long
7272
7373> The ` %rune% ` rune is only available inside ` .svelte ` and ` .svelte.js/ts ` files
7474
75+ ## set_context_after_init
76+
77+ > ` setContext ` must be called when a component first initializes, not in a subsequent effect or after an ` await ` expression
78+
7579## state_descriptors_fixed
7680
7781> Property descriptors defined on ` $state ` objects must contain ` value ` and always be ` enumerable ` , ` configurable ` and ` writable ` .
Original file line number Diff line number Diff line change 22
33import { DEV } from 'esm-env' ;
44import { lifecycle_outside_component } from '../shared/errors.js' ;
5+ import * as e from './errors.js' ;
56import { source } from './reactivity/sources.js' ;
67import {
78 active_effect ,
@@ -10,7 +11,7 @@ import {
1011 set_active_reaction
1112} from './runtime.js' ;
1213import { effect , teardown } from './reactivity/effects.js' ;
13- import { legacy_mode_flag } from '../flags/index.js' ;
14+ import { async_mode_flag , legacy_mode_flag } from '../flags/index.js' ;
1415
1516/** @type {ComponentContext | null } */
1617export let component_context = null ;
@@ -65,6 +66,13 @@ export function getContext(key) {
6566 */
6667export function setContext ( key , context ) {
6768 const context_map = get_or_init_context_map ( 'setContext' ) ;
69+
70+ if ( async_mode_flag ) {
71+ if ( /** @type {ComponentContext } */ ( component_context ) . m ) {
72+ e . set_context_after_init ( ) ;
73+ }
74+ }
75+
6876 context_map . set ( key , context ) ;
6977 return context ;
7078}
Original file line number Diff line number Diff line change @@ -197,6 +197,21 @@ export function hydration_failed() {
197197 }
198198}
199199
200+ /**
201+ * `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression
202+ * @returns {never }
203+ */
204+ export function set_context_after_init ( ) {
205+ if ( DEV ) {
206+ const error = new Error ( `set_context_after_init\n\`setContext\` must be called when a component first initializes, not in a subsequent effect or after an \`await\` expression\nhttps://svelte.dev/e/set_context_after_init` ) ;
207+
208+ error . name = 'Svelte error' ;
209+ throw error ;
210+ } else {
211+ throw new Error ( `https://svelte.dev/e/set_context_after_init` ) ;
212+ }
213+ }
214+
200215/**
201216 * Could not `{@render }` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}`
202217 * @returns {never }
Original file line number Diff line number Diff line change 1+ import { flushSync } from 'svelte' ;
2+ import { test } from '../../test' ;
3+
4+ export default test ( {
5+ async test ( { target, assert, logs } ) {
6+ const button = target . querySelector ( 'button' ) ;
7+
8+ flushSync ( ( ) => button ?. click ( ) ) ;
9+ assert . ok ( logs [ 0 ] . startsWith ( 'set_context_after_init' ) ) ;
10+ }
11+ } ) ;
Original file line number Diff line number Diff line change 1+ <script >
2+ import { setContext } from ' svelte' ;
3+
4+ let condition = $state (false );
5+
6+ $effect (() => {
7+ if (condition) {
8+ try {
9+ setContext (' potato' , {});
10+ } catch (e) {
11+ console .log (e .message );
12+ }
13+ }
14+ });
15+ </script >
16+
17+ <button onclick ={() => condition = ! condition }>
18+ {condition }
19+ </button >
You can’t perform that action at this time.
0 commit comments