Provide svelte compatible implementations of readable, writable, derived and get with strict inequality triggering semantics.
Strict inequality triggering semantics provide a store version of the functionality seen with <svelte:options immutable={true} /> in the svelte compiler.
Strict equality stores make the most sense when programming with strict immutability rules and functional programming.
For complex structured immutable types, try @crikey/stores-immer
# pnpm
$ pnpm add @crikey/stores-strict
# npm
$ npm add @crikey/stores-strict
# yarn
$ yarn add @crikey/stores-strict
Standard usage should be a drop in replacement for svelte/store
, with the exception of when subscriptions are
triggered.
Classic svelte stores signal for changes greedily. If a store value is updated and either the old or new value are complex types, then svelte will signal a change even if those values are strictly equal.
Strict stores use a simple referential inequality check (!==
) to determine if a change signal should be sent.
e.g.
const store = writable([1]);
// log each change
store.subscribe(arr => console.log(arr));
// don't change anything
store.update(arr => {
return arr;
});
// push an item onto the array
store.update(arr => {
arr.push(2);
return arr;
});
// @crikey/stores-strict
// > [1]
//
// @crikey/stores-svelte (svelte compatible stores)
// > [1]
// > [1]
// > [1,2]
//
the constant value of the store
Derives a store from one or more other stores. The store value is calculated on demand and recalculated whenever any of the store dependencies change.
For simple usage, see the alternate signature.
Values may be updated asynchronously:
Example:
From ./packages/stores-strict/examples/derive.test.ts#99~127
const store_a = writable(1);
const auto_increment = derive(
store_a,
(a, { update }) => {
const intervalId = setInterval(
() => { update(value => value + a); },
1000
);
return () => {
clearTimeout(intervalId);
}
},
0
);
auto_increment.subscribe(value => console.log('store value:', value));
await new Promise(resolve => {
setTimeout(resolve, 3500);
});
// > store value: 0
// > store value: 1
// > store value: 2
// > store value: 3
input stores
callback that aggregates the store values which are passed in as the first argument
Derives a store from one or more other stores. The store value is calculated on demand and recalculated whenever any of the store dependencies change.
For simple usage, see the alternate signature.
Values may be updated asynchronously:
Example:
From ./packages/stores-strict/examples/derive.test.ts#99~127
const store_a = writable(1);
const auto_increment = derive(
store_a,
(a, { update }) => {
const intervalId = setInterval(
() => { update(value => value + a); },
1000
);
return () => {
clearTimeout(intervalId);
}
},
0
);
auto_increment.subscribe(value => console.log('store value:', value));
await new Promise(resolve => {
setTimeout(resolve, 3500);
});
// > store value: 0
// > store value: 1
// > store value: 2
// > store value: 3
input stores
callback that aggregates the store values which are passed in as the first argument
initial value - useful when the aggregate function initialises the store asynchronously
Derives a store from one or more other stores. The store value is calculated on demand and recalculated whenever any of the store dependencies change.
In the simplest version, derive
takes a single store, and the callback returns a derived value:
Example:
From ./packages/stores-strict/examples/derive.test.ts#11~25
const store_a = writable(1);
const doubled = derive(
store_a,
a => a * 2
);
doubled.subscribe(value => console.log('store value:', value));
store_a.set(2);
// > store value: 2
// > store value: 4
derive
may also take a tuple or array of inputs a derive a value from those:
Example:
From ./packages/stores-strict/examples/derive.test.ts#36~51
const store_a = writable(1);
const store_b = writable(100);
const summed = derive(
[store_a, store_b],
([a, b]) => a + b
);
summed.subscribe(value => console.log('store value:', value));
store_a.set(2);
// > store value: 101
// > store value: 102
Alternate signatures provide a means for deriving the value asynchronously.
input stores
callback that aggregates the store values
Creates a readable store with the value of undefined
.
This signature provides little benefit other than mirroring the signature for its counterpart, readable
Example:
From ./packages/stores-strict/examples/readable.test.ts#8~14
const store = readable();
store.subscribe(value => { console.log('store value:', value) });
// > store value: undefined
Explicitly defining the type of store via readable<Type>
will
result in a store of type Readable<Type | undefined>
to allow for the default value.
If this is undesired, an alternate default value/type can be provided.
Creates a readable store with an initial value of value
.
Readable stores provide no external methods for changing the store value, but their value can be changed via
the implementation of start
.
See writable for detailed usage of the start
argument.
Example:
From ./packages/stores-strict/examples/readable.test.ts#25~50
const time = readable<Date | null>(null, (set) => {
set(new Date());
const intervalId = setTimeout(() => {
set(new Date());
}, 1000);
return () => {
clearInterval(intervalId);
}
});
const unsubscribe = time.subscribe(value => { console.log('time is:', value) });
// wait 1 second
await new Promise(resolve => {
setTimeout(resolve, 1000);
});
unsubscribe();
// > time is: ...
// > time is: ...
initial store value
callback which is signaled whenever the number of subscribers changes from 0 to 1
Create a writable store with an initial value of undefined
.
Writable stores allow the store value to be set and updated by external code via Writable.set and Writable.update.
Example:
From ./packages/stores-strict/examples/writable.test.ts#8~30
// create a writable store
const store = writable<number>();
// log each store value
store.subscribe(value => console.log(value))
// set
store.set(1);
// update
store.update(value => value === undefined ? 0 : value + 1);
// set
store.set(undefined);
// > undefined
// > 1
// > 2
// > undefined
Explicitly defining the type of store via writable<Type>
will
result in a store of type Writable<Type | undefined>
to allow for the default value.
If this is undesired, an alternate default value/type can be provided.
Create a writable store with an initial value of value
.
Writable stores allow the store value to be set and updated by external code via Writable.set and Writable.update.
Example:
From ./packages/stores-strict/examples/writable.test.ts#43~61
// create a writable store
const store = writable(42);
// log each store value
store.subscribe(value => console.log(value))
// set
store.set(1);
// update
store.update(value => value + 1);
// > 42
// > 1
// > 2
If start
is provided, it will be called when the number of subscribers goes from zero to one (but not from one
to two, etc). Thus, start
is called whenever the writable store 'starts up'.
start
may optionally return a function which will be called when the last subscriber unsubscribes.
Example:
From ./packages/stores-strict/examples/writable.test.ts#73~98
// create a writable store
const store = writable(42, () => {
console.log('got a subscriber');
return () => console.log('no more subscribers');
});
// log each store value
const unsubscribe = store.subscribe(value => console.log(value))
// set
store.set(1);
// update
store.update(value => value + 1);
unsubscribe();
// > got a subscriber
// > 42
// > 1
// > 2
// > no more subscribers
start
is passed 4 functions - set
, update
, invalidate
, and validate
.
start
: set
Set the current value of the store (and thus marking the store value as valid).
Example:
From ./packages/stores-strict/examples/writable.test.ts#112~139
// create a writable store which updates asynchronously
const store = writable(false, (set) => {
const id = setTimeout(
() => { set(true) },
0
);
return () => {
clearTimeout(id);
};
});
// log each store value
const unsubscribe = store.subscribe(value => console.log('store value:', value))
// give time for an update
await new Promise(resolve => {
setTimeout(resolve, 0);
});
unsubscribe();
// > store value: false
// > store value: true
start
: update
Update the current value of the store (and thus marking the store value as valid).
Example:
From ./packages/stores-strict/examples/writable.test.ts#150~177
// create a writable store which updates asynchronously
const store = writable(5, ({ update }) => {
const id = setTimeout(
() => { update(value => value * 1000) },
0
);
return () => {
clearTimeout(id);
};
});
// log each store value
const unsubscribe = store.subscribe(value => console.log('store value:', value))
// give time for an update
await new Promise(resolve => {
setTimeout(resolve, 0);
});
unsubscribe();
// > store value: 5
// > store value: 5000
start
: invalidate
Mark the store (and any dependencies) as dirty. Only necessary when creating advanced stores such as derive.
start
: validate
Mark the store (and any dependencies) as valid. Only necessary when creating advanced stores such as derive.
Usage of invalidate
and validate
is only necessary when creating advanced stores such as derive which are
dependent on other stores but should only be recalculated once all dependent stores are in a valid state.
initial store value
callback called whenever the number of subscribers changes from 0 to 1
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Initial value of the resulting store
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Initial value of the resulting store
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Creates a new TransformedStore store by applying transform functions on both read and write.
input store
callback used to transform values from the input store into values for the output store
callback used setting the value of the output store. result is applied to the input store.
Return the current value of the provided store
.
Works by subscribing and immediately unsubscribing from the given store
.
This is neither efficient nor reactive and should generally be avoided.
Example:
From ./packages/stores-base/examples/get.test.ts#8~12
const store = writable(trigger_strict_not_equal, 42);
console.log(get(store)); // > 42
store
to get the value from
the current store
value
Generated using TypeDoc
Create a simple store which always returns the same value upon subscription
Example:
From ./packages/stores-base/examples/constant.test.ts#8~14