Repository: sveltejs/svelte
File: packages/svelte/src/internal/client/reactivity/props.js (JavaScript)

Code before:
			if (arguments.length > 0) {
				// We don't want to notify if the value was mutated and the parent is in runes mode.
				// In that case the state proxy (if it exists) should take care of the notification.
				// If the parent is not in runes mode, we need to notify on mutation, too, that the prop
				// has changed because the parent will not be able to detect the change otherwise.
				if (!runes || !mutation || legacy_parent || is_store_sub) {
					/** @type {Function} */ (setter)(mutation ? getter() : value);
				}

				return value;
			}

			return getter();
		};
	}

	// prop is written to, but there's no binding, which means we
	// create a derived that we can write to locally
	var d = ((flags & PROPS_IS_IMMUTABLE) !== 0 ? derived : derived_safe_equal)(getter);

	// Capture the initial value if it's bindable
	if (bindable) get(d);

	return function (/** @type {any} */ value, /** @type {boolean} */ mutation) {
		if (arguments.length > 0) {
			const new_value = mutation ? get(d) : runes && bindable ? proxy(value) : value;

			set(d, new_value);

			if (fallback_value !== undefined) {
				fallback_value = new_value;
			}

			return value;
		}

		// TODO is this still necessary post-#16263?
		if (has_destroyed_component_ctx(d)) {
			return d.v;
		}

		return get(d);
	};
}


Review comment (suggestion):
Found it strange that the "in Svelte 4 ..." logic above in the getter was removed - did some digging and turns out that #11577 was added back when we did return the getter above in legacy mode too. Now that logic is obsolete, but we should add a comment here explaining why we need it in legacy mode, too
```suggestion
	// Either prop is written to, but there's no binding, which means we
	// create a derived that we can write to locally.
	// Or we are in legacy mode where we always create a derived to replicate that
	// Svelte 4 did not trigger updates when a primitive value was updated to the same value.
```

Code after:
	}

	// prop is written to, but the parent component had `bind:foo` which
	// means we can just call `$$props.foo = value` directly
	if (setter) {
		var legacy_parent = props.$$legacy;

		return function (/** @type {any} */ value, /** @type {boolean} */ mutation) {
			if (arguments.length > 0) {
				// We don't want to notify if the value was mutated and the parent is in runes mode.
				// In that case the state proxy (if it exists) should take care of the notification.
				// If the parent is not in runes mode, we need to notify on mutation, too, that the prop
				// has changed because the parent will not be able to detect the change otherwise.
				if (!runes || !mutation || legacy_parent || is_store_sub) {
					/** @type {Function} */ (setter)(mutation ? getter() : value);
				}

				return value;
			}

			return getter();
		};
	}

	// prop is written to, but there's no binding, which means we
	// create a derived that we can write to locally
	var d = ((flags & PROPS_IS_IMMUTABLE) !== 0 ? derived : derived_safe_equal)(getter);

	// Capture the initial value if it's bindable
	if (bindable) get(d);

	return function (/** @type {any} */ value, /** @type {boolean} */ mutation) {
		if (arguments.length > 0) {
			const new_value = mutation ? get(d) : runes && bindable ? proxy(value) : value;

			set(d, new_value);

			if (fallback_value !== undefined) {
				fallback_value = new_value;
			}

			return value;
		}

		// TODO is this still necessary post-#16263?
		if (has_destroyed_component_ctx(d)) {
			return d.v;
		}

		return get(d);
	};