Skip to content

Ability to select store properties to filter reactivity / derived #8470

@oodavid

Description

@oodavid

Describe the problem

When a store exposes a complex object, we may want to selectively rebuild based on properties.

For example, a store may expose a User:

interface User {
	name: string;
	email: string;
	dob: Date;
};
const user = writable<User>();

We may calculate our age from the date.
If we only want to recalculate if the dob property has changed, we have to put extra checks in place.

let age: number | undefined;
let lastDobTime: number | undefined;
$: {
	// Check that the properties we're interested in haven't changed
	const dobTime = $user.dob.getTime();
	if (dobTime != lastDobTime) {
		lastDobTime = dobTime;
		// The actual logic
		var diff_ms = Date.now() - dobTime;
		var age_dt = new Date(diff_ms);
		age = Math.abs(age_dt.getUTCFullYear() - 1970);
	}
}

...you could see how these checks could bloat with more complex logic

Describe the proposed solution

Have a way to select properties from stores, like so:

let age: number | undefined;
$: dobTime = user.select(($user) => $user.dob.getTime());
$: {
	var diff_ms = Date.now() - dobTime;
	var age_dt = new Date(diff_ms);
	age = Math.abs(age_dt.getUTCFullYear() - 1970);
}

NB, if #8469 was implemented, we could do this with a reactive store:

const age = reactive<number>((set) => {
	const dobTime = user.select(($user) => $user.dob.getTime());
	var diff_ms = Date.now() - dobTime;
	var age_dt = new Date(diff_ms);
	set(Math.abs(age_dt.getUTCFullYear() - 1970));
});

Alternatives considered

Once again, I'm taking inspiration from the Riverpod package for Dart / Flutter. It has a lot of similar goals and behaviours as svelte stores.

https://riverpod.dev/docs/concepts/reading#using-select-to-filter-rebuilds

Importance

would make my life easier

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions