Provide svelte compatible implementations of readable
, writable
, derived
and get
using immutible values via immer.
Strict inequality triggering semantics provide a store version of the functionality seen with <svelte:options immutable={true} /> in the svelte compiler.
Using immer, @crikey/stores-immer
is able to provide copy-on-write semantics
during updates.
See @crikey/stores-immer for full documentation.
# pnpm
$ pnpm add @crikey/stores-immer
# npm
$ npm add @crikey/stores-immer
# yarn
$ yarn add @crikey/stores-immer
Standard usage should be a drop in replacement for svelte/store
.
The key difference being that mutating a store value will use immer to perform
copy-on-write semantics during an Writable.update | update
.
const initial = [1,2,3];
const store = writable([1,2,3]);
store.subscribe(value => console.log(value));
// > [ 1, 2, 3 ]
store.update(value => {
value.push(4);
return value;
})
// > [ 1, 2, 3, 4 ]
console.log(get(store) !== initial);
// > true
Synchronous callback for deriving a value from resolved input value
A Writable store which contains the most recent of either:
read
transformset
or update
Additionally contains two other stores: {@link derived$} {@link smart$}
Asynchronous callback for deriving a value from resolved input value
Synchronous callback for deriving a value from resolved input value
Create a simple store which always returns the same value upon subscription
Example:
From ./packages/stores-base/examples/constant.test.ts#8~14
const store = constant(10);
console.log('store value:', get(store));
// > store value: undefined
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-base/examples/writable.test.ts#8~30
// create a writable store
const store = writable<number>(trigger_strict_not_equal);
// 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
Updates to the store value via Writable.update have copy-on-write semantics via immer.
From ./packages/stores-immer/examples/writable.test.ts#8~22
const initial = [1,2,3];
const store = writable([1,2,3]);
store.subscribe(value => console.log(value));
// > [ 1, 2, 3 ]
store.update(value => {
value.push(4);
return value;
})
// > [ 1, 2, 3, 4 ]
console.log(get(store) !== initial);
// > true
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-base/examples/writable.test.ts#43~61
// create a writable store
const store = writable(trigger_strict_not_equal, 42);
// log each store value
store.subscribe(value => console.log(value))
// set
store.set(1);
// update
store.update(value => value + 1);
// > 42
// > 1
// > 2
Updates to the store value via Writable.update have copy-on-write semantics via immer.
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-base/examples/writable.test.ts#73~98
// create a writable store
const store = writable(trigger_strict_not_equal, 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-base/examples/writable.test.ts#112~139
// create a writable store which updates asynchronously
const store = writable(trigger_strict_not_equal, 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-base/examples/writable.test.ts#150~177
// create a writable store which updates asynchronously
const store = writable(trigger_strict_not_equal, 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
Asynchronous callback for deriving a value from resolved input value