This adds load functionality to readable/writable stores. They both include load functions that give you a promise that resolves when the store is first set (either through their start function, or through being set externally)
This lets you delay application steps that need to happen after these stores get a value, without forcing you to use promises/async functions to load the store like you need to do for async stores.
Simple example:
<script>
const hasConsent = writable(undefined, (set) => {
const setConsent = set(true);
addEventListener('CONSENT_EVENT', setConsent);
return () => removeEventListener('CONSENT_EVENT', setConsent);
});
const needsConsent = asyncDerived(
(hasConsent),
async ($hasConsent) => {
// this won't run until hasConsent has loaded
if (!$hasConsent) {
return "no consent given"
}
const asyncMessage = await Promise.resolve('data fetched from server');
return asyncMessage;
}
);
</script>
<button on:click={() => hasConsent.set(true)>I consent!</button>
<button on:click={() => hasConsent.set(false)>I don't consent!</button>
{#await needsConsent.load()}
<p>I will only load after hasConsent has been populated</p>
<p>{$needsConsent}</p>
{/await}
Note how, unlike async stores, we can return an unsubscribe function to clean up the event listener when this component is destroyed.
Previous points of disucssion, before I decided to move forward having these replace readable/writable stores
One area of discussion: Should these be separate stores? Or should they supplant default `readable` and `writable` stores (like we do for derived, by reexporting).
The three main benefits of replacing readable and writable are that
1. it allows for this behavior by default when switching over to @square/svelte-store without needing to update a bunch of stores
2. It reduces the number of new store types that this package exports, simplifying our documentation and reducing the spin up time of learning when to use these different stores.
3. It means that *every* store is loadable, which allows us to simplify the typing and logic surrounding that.
The two possible downsides are:
1. added memory consumption and complexity to all readable and wrtitable stores
2. It is possible this could break some people's apps--If someone creates an store with an undefined value and then never sets it to a different value, then the store will never 'load' and thus will block anything that relies on that completing (like asyncDerived stores)
This is a potentially breaking change, so I am bumping the version to 0.2.0
Example break in stores/messages.ts
unreadMessageCount derives from an asynchronous source, and from a readable source. When updatedMessageCount (set by the event listener) has a value, that value is used instead of the initializedMessageCount. Since updatedMessageCount starts as undefined, it will not 'load' until the event listener fires. This means that unreadMessageCount will not load until then either, which is not the intended behavior.
This is fixed in 0.2.0 by providing 'null' as the initial value of the updatedMessageCount store instead of 'undefined'
This adds load functionality to readable/writable stores. They both include load functions that give you a promise that resolves when the store is first
set
(either through their start function, or through being set externally)This lets you delay application steps that need to happen after these stores get a value, without forcing you to use promises/async functions to load the store like you need to do for async stores.
Simple example:
Note how, unlike async stores, we can return an unsubscribe function to clean up the event listener when this component is destroyed.
Previous points of disucssion, before I decided to move forward having these replace readable/writable stores
This is a potentially breaking change, so I am bumping the version to 0.2.0 Example break in stores/messages.ts
unreadMessageCount derives from an asynchronous source, and from a readable source. When updatedMessageCount (set by the event listener) has a value, that value is used instead of the initializedMessageCount. Since updatedMessageCount starts as undefined, it will not 'load' until the event listener fires. This means that unreadMessageCount will not load until then either, which is not the intended behavior.
This is fixed in 0.2.0 by providing 'null' as the initial value of the updatedMessageCount store instead of 'undefined'