Types and functions for creating Svelte compatible stores.
@crikey/stores-dynamic
stores further extend the svelte/store
contract to allow for dynamic dependencies and natural error handling.
# pnpm
$ pnpm add @crikey/stores-dynamic
# npm
$ npm add @crikey/stores-dynamic
# yarn
$ yarn add @crikey/stores-dynamic
Dynamic stores store more than just a simple value, instead they store a DynamicResolved which can itself contain a value via DynamicValue, or an error via DynamicError. Storing values and errors separately facilitates error handling.
Any Readable containing an object with either a value
or error
property is considered a
DynamicReadable and can safely be mixed with this library.
The kind of dynamic can be ascertained by querying its properties. An object with an error
property is a
DynamicError, an object with a value
property is a DynamicValue and an object with a subscribe
function is a Readable.
Being able to distinguish types in this way allows for a cohesive syntax when dealing with otherwise arbitrary inputs.
The dynamic function has many signatures:
dynamic(store)
Convert a regular Readable store to a DynamicReadable by wrapping its value via DynamicValue
dynamic([trigger,] [args,] calculate [,initial_value])
trigger
- Optional function used for comparing DynamicResolved values and determining if subscribers should be calledargs
- Optional array of arbitrary data to be passed as-is as the first argument to calculate
calculate([args,] resolve [,set])
- Callback used to derive the store value. Will be called each time any of the dependencies changeinitial_value
- Initial value of the store. Useful when calculate
is async.If args
are provided to dynamic
, they are passed unchanged to calculate
as the first argument.
If calculate
accepts an argument after resolve
, it is deemed asynchronous.
resolve
can be used to obtain the inner value of any Dynamic.
resolve
is called with a DynamicReadable store, then the store will be added as a dependency.resolve
is called with a DynamicError or a DynamicReadable which resolves to a DynamicError, the contained error will be thrown.
Each execution of calculate
will subscribe to new stores as required and unsubscribe to stores no longer required.Synchronous dynamic stores which are only dependent on constant inputs (see: DynamicFlagConstant) will be cached.
This can be avoided by setting is_const
in the result of calculate
.
Example: Dynamic dependencies
import {writable} from "@crikey/stores-strict";
import {dynamic} from "@crikey/stores-dynamic";
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
Hold an error thrown during the evaluation of a dynamic item
Flag Dynamic value to determine if deriving calculation is static
A store containing a dynamic result
Hold the resolved value or error of a dynamic item
Hold the resolved value of a dynamic item
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
Create a simple store which always returns the same result - a DynamicError containing error.
Example:
From ./packages/stores-dynamic/examples/constant.test.ts#41~48
const error = new Error('my error');
const store = constant_error(error);
console.log('store value:', get(store));
// > store value: undefined
Create a simple store which always returns the same result - a DynamicValue containing value.
Example:
From ./packages/stores-dynamic/examples/constant.test.ts#25~31
const store = constant_value(10);
console.log('store value:', get(store));
// > store value: undefined
the constant value of the store
Creates a trigger function for DynamicResolved values
trigger function for comparing values
trigger function for comparing errors
Default trigger used in dynamics when none is specified
Transforms a regular store into a dynamic store by transforming its value into a @{link DynamicValue}
See other signatures for alternate semantics
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#10~17
const store = readable(1);
const derived = dynamic(store);
console.log('derived value:', get(derived));
the input store to transform
if true, creates a cheap wrapper around each subscription instead of a fully derived store
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For asynchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#59~82
const a = writable({ value: { prop: 1 } });
const derived = dynamic(
(resolve) => {
try {
return { value: resolve(a)['prop'] }
}
catch (ex) {
// natural place for error handling
throw ex;
}
}
);
derived.subscribe((value) => console.log('derived value:', value))
// @ts-ignore
a.set({ value: null });
// > derived value: { value: 1, dependencies: [a] }
// > derived value: { error: TypeError, dependencies: [a] }
callback used to determine if subscribers should be called
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to determine if subscribers should be called
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to determine if subscribers should be called
callback used to calculate the resulting store value
initial value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For asynchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#59~82
const a = writable({ value: { prop: 1 } });
const derived = dynamic(
(resolve) => {
try {
return { value: resolve(a)['prop'] }
}
catch (ex) {
// natural place for error handling
throw ex;
}
}
);
derived.subscribe((value) => console.log('derived value:', value))
// @ts-ignore
a.set({ value: null });
// > derived value: { value: 1, dependencies: [a] }
// > derived value: { error: TypeError, dependencies: [a] }
callback used to determine if subscribers should be called
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to determine if subscribers should be called
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to determine if subscribers should be called
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
initial value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For asynchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#59~82
const a = writable({ value: { prop: 1 } });
const derived = dynamic(
(resolve) => {
try {
return { value: resolve(a)['prop'] }
}
catch (ex) {
// natural place for error handling
throw ex;
}
}
);
derived.subscribe((value) => console.log('derived value:', value))
// @ts-ignore
a.set({ value: null });
// > derived value: { value: 1, dependencies: [a] }
// > derived value: { error: TypeError, dependencies: [a] }
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
callback used to calculate the resulting store value
initial value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For asynchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#59~82
const a = writable({ value: { prop: 1 } });
const derived = dynamic(
(resolve) => {
try {
return { value: resolve(a)['prop'] }
}
catch (ex) {
// natural place for error handling
throw ex;
}
}
);
derived.subscribe((value) => console.log('derived value:', value))
// @ts-ignore
a.set({ value: null });
// > derived value: { value: 1, dependencies: [a] }
// > derived value: { error: TypeError, dependencies: [a] }
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
Derives a store via a calculation callback. Calculations can be dependent on any number of stores
and will be recalculated as needed,
Note: Whilst an array of arguments can be provided to be passed to the calculation, store dependencies need
not be included in this list.
The only requirement is that they be resolved via the resolve
function passed to the calculate
callback.
Equivalent of derive, but store dependencies are determined dynamically as needed.
For synchronous usage, see alternate signatures.
Example:
From ./packages/stores-dynamic/examples/dynamic.test.ts#27~47
const a = writable({ value: 0 });
const b = writable({ value: 'b value' });
const c = writable({ value: 'c value' });
const derived = dynamic(
(resolve) => {
return resolve(a) % 2 === 0
? { value: resolve(b) }
: { value: resolve(c) }
}
);
derived.subscribe((value) => console.log('derived value:', value))
a.set({ value: 1 });
// > derived value: { value: 'b value', dependencies: [a, b] }
// > derived value: { value: 'c value', dependencies: [a, c] }
array of arguments to be passed to the callback unchanged
callback used to calculate the resulting store value
initial value
Uses get to retrieve the current dynamic value and return its value property (or undefined)
Uses get to retrieve the current dynamic value and return its value property (or default_)
The value to return if no value is present
Returns true if the given argument is a DynamicError
Returns true if the given argument is a DynamicResolved value (has either a value or an error property)
Returns true if the given argument is a resolved value (has either a value or an error property)
Returns true if the given argument is a DynamicValue
Returns true if the given argument is a DynamicValue
Returns item unchanged
See alternate signatures for the real utility of this function
Returns item unchanged
See alternate signatures for the real utility of this function
Returns item unchanged
See alternate signatures for the real utility of this function
Resolve store to a constant DynamicResolved value (on demand) if possible, or keep as a DynamicReadable.
If item is not a store, returns the item unchanged.
If item is a store: Upon initial introspection, the store is subscribed. If the resulting value is is static then it is cached, otherwise the store is cached. Future introspections operate solely on the cache.
The net result is that values that can be calculated statically are only calculated once, but values which are calculated based off of dynamic dependencies will need to be calculated again upon subsequent subscriptions. Thus, for a single subscription the dynamic value will be calculated at least twice.
Generated using TypeDoc
Any kind of dynamic item