Interfaces
info
This Section might be useless to you without any context. As the name suggests, it's all about typescript interfaces of AgileTs. These interfaces are outsourced for a better overview, maintainability, and reusability. You might get redirected to parts of the Interface Section from other documentation to learn more about specific Interfaces.
StateIngestConfig
The StateIngestConfigInterface
is used as configuration object in functions like set()
or undo()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface StateIngestConfigInterface
extends StateRuntimeJobConfigInterface,
IngestConfigInterface {
key?: RuntimeJobKey;
}
Note: The StateIngestConfigInterface
extends some other Interfaces:
key
The key/name
of the Job that is created and ingested into the runtime
.
MY_STATE.set('hello there', {key: 'jeff'});
Such key can be very useful during debug sessions
in order to analyse when which Job ran through the runtime
.
// Agile Debug: Created Job 'jeff', Job('jeff')
// Agile Debug: Completed Job 'jeff', Job('jeff')
// Agile Debug: Updated/Rerendered Subscriptions, [SubscriptionContainer, ..]
Type | Default | Required |
---|---|---|
string \| number | undefined | No |
StateRuntimeJobConfig
The StateRuntimeJobConfigInterface
is used as configuration object in functions like replace()
or select()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface StateRuntimeJobConfigInterface
extends RuntimeJobConfigInterface {
overwrite?: boolean;
storage?: boolean;
}
Note: The StateRuntimeJobConfigInterface
extends some other Interfaces:
overwrite
If true
, the whole State is overwritten with the newly assigned value
.
MY_STATE.set("finalValue", {overwrite: true});
MY_STATE.value; // Returns 'finalValue'
MY_STATE.previousStateValue; // Returns 'finalValue'
MY_STATE.initialStateValue; // Returns 'finalValue'
During the overwrite process, the following properties are overwritten:
value
previousStateValue
initalStateValue
isPlaceholder
Type | Default | Required |
---|---|---|
boolean | false | No |
storage
Whether to apply the State value changes to the corresponding external Storage/s.
const MY_STATE = createState('jeff').persist('storageKey');
// Storage at 'storageKey': 'jeff'
MY_STATE.set("hans", {storage: true});
// Storage at 'storageKey': 'hans'
MY_STATE.set("dieter", {storage: false});
// Storage at 'storageKey': 'hans'
Be aware that this is only relevant, if the State is persisted.
We can use the isPersisted
property to check whether a state is persisted.
MY_STATE.isPersisted;
Type | Default | Required |
---|---|---|
boolean | true | No |
RuntimeJobConfigInterface
The RuntimeJobConfigInterface
is used in the creation and configuration of a Runtime Job
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface RuntimeJobConfigInterface {
background?: boolean;
sideEffects?: SideEffectConfigInterface;
force?: boolean;
numberOfTriesToUpdate?: number | null;
}
background
When true
, the Job is executed in the background
and won't cause any rerender on Components that have subscribed the Agile Sub Instance
represented by the Job.
// Causes rerender on Components
MY_STATE.set("myNewValue2");
// Doesn't cause rerender on Components
MY_STATE.set("myNewValue3", {background: true});
Type | Default | Required |
---|---|---|
boolean | false | No |
sideEffects
Specifies whether the side effects of the Job should be executed.
// Executes sideEffects
MY_STATE.set("myNewValue2");
// Doesn't execute sideEffects
MY_STATE.set("myNewValue3", {sideEffects: false});
During a side effect, several essential tasks are done. These include, for example, rebuilding the Group output of a Group or updating the persisted State value in the corresponding external Storage.
Type | Default | Required |
---|---|---|
boolean | true | No |
force
When set to true
, the Job is forced through the runtime
no matter what happens.
const MY_STATE = createState('myValue');
// Won't be executed by the runtime because the State value hasn't changed
MY_STATE.set('myValue');
// Will be executed by the runtime, although the State value hasn't changed
MY_STATE.set('myValue', { force: true });
Type | Default | Required |
---|---|---|
boolean | false | No |
numberOfTriesToUpdate
How often the runtime should try to update not ready SubscriptionContainers of the Job.
If the update tries count exceeds the numberOfTriesToUpdate
count,
the Job will be entirely removed from the runtime.
This has the advantage that an overflow of the runtime is avoided.
If numberOfTriesToUpdate
is null
the runtime tries to update the not ready Job subscriptionContainers
until they are ready.
Type | Default | Required |
---|---|---|
number \| null | 3 | No |
IngestConfigInterface
The IngestConfigInterface
is used as a configuration object to configure the ingest process of Jobs
into the runtime
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface IngestConfigInterface {
perform?: boolean;
}
perform
Whether the ingested Job should be executed immediately by the runtime
or should first be inserted into a queue
and performed when it is its turn.
Type | Default | Required |
---|---|---|
boolean | true | No |
PatchConfig
The PatchConfigInterface
is used as configuration object in functions like patch()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface PatchConfigInterface extends StateIngestConfigInterface {
addNewProperties?: boolean;
}
Note: The PatchConfigInterface
extends some other Interfaces:
addNewProperties
If true
, new properties are added to the State value, although they might not yet be present there.
const MY_STATE = createState({id: 1, name: "frank"});
MY_STATE.patch({location: "Germany"}, {addNewProperties: false});
MY_STATE.value; // Returns {id: 1, name: "frank"}
MY_STATE.patch({location: "Germany"}, {addNewProperties: true});
MY_STATE.value; // Returns {id: 1, name: "frank", location: "Germany"}
Type | Default | Required |
---|---|---|
boolean | true | No |
StatePersistentConfig
The StatePersistentConfigInterface
is used as configuration object in functions like persist()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface StatePersistentConfigInterface {
key?: string | number;
loadValue?: boolean;
storageKeys?: StorageKey[];
onMigrate?: (value: any) => ValueType;
onSave?: (value: ValueType) => any;
}
loadValue
When true
, the created Persistent
automatically loads the value stored in the corresponding external Storage into the State.
Or, if the State isn't persisted yet, it stores the State value in the corresponding external Storage.
Be aware that if we don't allow the Persistent
to load/store the value, we have to do it ourselves.
myState.persist({
loadValue: false,
});
if (myState.persistent?.ready) {
await myState.persistent?.initialLoading();
myState.isPersisted = true;
}
Loading the value manually has one advantage.
It allows us to await the asynchronous load/store process.
If you only need to await the loading process we recommend using the onLoad()
method.
Type | Default | Required |
---|---|---|
boolean | true | No |
storageKeys
Specifies the Storage/s the State value should be persisted in.
MY_STATE.persist(); // Stores value in default Storage
MY_STATE.persist({storageKeys: ['myCustomStorrage']}); // Stores value in 'myCustomStorrage'
If no specific Storage defined, the State value will be stored/persisted in the default Storage.
Type | Default | Required |
---|---|---|
Array<string \| number> | 'defaultStorage' | No |
GroupConfig
The GroupConfigInterface
is used in the creation and configuration of the Group Class
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface GroupConfigInterface {
key?: GroupKey;
isPlaceholder?: boolean;
}
key
The optional property key/name
should be a unique string/number
to identify the Group later.
MY_COLLECTION.createGroup([1, 2, 3], {
key: "myKey"
});
We recommend giving each Group a unique key
since it has only advantages:
- helps us during debug sessions
- makes it easier to identify the Group
- no need for separate persist Key
Type | Default | Required |
---|---|---|
string \| name | undefined | No |
isPlaceholder
Defines whether the Group is a placeholder
.
const MY_GROUP = createGroup([1, 2, 3], {
isPlaceholder: true
});
MY_GROUP.exists(); // false
Groups are placeholder
when AgileTs needs to hold a reference to them,
even though they aren't instantiated yet.
This can be the case if we use the getGroupWithReference()
method,
which returns a placeholder
Group if the Group we are looking for doesn't exist yet.
const myGroup = useAgile(MY_COLLECTION.getGroupWithReference("group1")); // Causes rerender if Group got created
const myGroup2 = useAgile(MY_COLLECTION.getGroup("group2")); // Doesn't causes rerender if Group got created
This reference is essential to rerender the Component, whenever the Group got instantiated.
Type | Default | Required |
---|---|---|
boolean | false | No |
SelectorConfig
The SelectorConfigInterface
is used in the creation and configuration of the Selector Class
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface SelectorConfigInterface {
key?: SelectorKey;
isPlaceholder?: boolean;
}
key
The optional property key/name
should be a unique string/number
to identify the Selector later.
MY_COLLECTION.createSelector(1, {
key: "myKey"
});
We recommend giving each Selector a unique key
since it has only advantages:
- helps us during debug sessions
- makes it easier to identify the Selector
- no need for separate persist Key
Type | Default | Required |
---|---|---|
string \| name | undefined | No |
isPlaceholder
Defines whether the Selector is a placeholder
.
const MY_SELECTOR = MY_COLLECTION.createSelector(1, {
isPlaceholder: true
});
MY_SELECTOR.exists(); // false
Selectors are placeholder
when AgileTs needs to hold a reference to them,
even though they aren't instantiated yet.
This can be the case if we use the getSelectorWithReference()
method,
which returns a placeholder
Selector if the Selector we are looking for doesn't exist yet.
const mySeleector = useAgile(MY_COLLECTION.getSelectorWithReference("selector1")); // Causes rerender if Selector got created
const mySeleector2 = useAgile(MY_COLLECTION.getSelector("selector2")); // Doesn't causes rerender if Selector got created
This reference is essential to rerender the Component, whenever the Selector got instantiated.
Type | Default | Required |
---|---|---|
boolean | false | No |
CollectConfig
The CollectConfigInterface
is used as configuration object in functions like collect()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface CollectConfigInterface<DataType = any> {
patch?: boolean;
method?: 'push' | 'unshift';
forEachItem?: (data: DataType, key: ItemKey, index: number) => void;
background?: boolean;
select?: boolean;
}
patch
info
The patch
property is only relevant to us
if we collect a data object with an already existing primaryKey
in order to update the Item data at that primaryKey
.
If true
, the passed data object is merged into the found Item data instead of overwriting it entirely.
const MY_COLLECTION = createCollection({
initialData: [{id: 1, name: 'frank', age: 10}]
});
MY_COLLECTION.collect({id: 1, name: 'hans'}, [], {patch: true});
MY_COLLECTION.getItemValue(1); // Returns '{id: 1, name: 'hans', age: 10}'
MY_COLLECTION.collect({id: 1, name: 'jeff'}, [], {patch: false});
MY_COLLECTION.getItemValue(1); // Returns '{id: 1, name: 'frank'}'
An alternative to this way of updating already existing Item data is the update()
method.
Type | Default | Required |
---|---|---|
boolean | false | No |
method
Specifies the way of adding the collected data primaryKey/s
to the defined Group/s.
push
The primaryKey
is added to the end of the Group value array.
MY_COLLECTION.collect({id: 1, name: "jeff"}, [], {method: 'push'});
MY_COLLECTION.getGroup(MY_COLLECTION.config.defaultGroupKey).value; // Returns [5, 6, 0, 1]
unshift
The primaryKey
is added to the beginning of the Group value array.
MY_COLLECTION.collect({id: 8, name: "jeff"}, [], {method: 'unshift'});
MY_COLLECTION.getGroup(MY_COLLECTION.config.defaultGroupKey).value; // Returns [8, 5, 6, 0, 1]
Type | Default | Required |
---|---|---|
push' \| 'unshift' | 'push' | No |
forEachItem
Callback that is called for each collected data object.
MY_COLLECTION.collect([
{id: 1, name: "jeff"},
{id: 8, name: "frank"}],
[],
{forEachItem: (data, key, index) => {
// Is called with 'data: {id: 1, name: "jeff"}, key: 1, index: 0'
// and
// Is called with 'data: {id: 2, name: "frank"}, key: 8, index: 1'
}
});
Type | Default | Required |
---|---|---|
(data: DataType, key: ItemKey, index: number) => void | undefined | No |
background
When true
, the data object/s are collected in background
and won't cause any rerender on Components that have subscribed the Collection.
// Causes rerender on Components
MY_COLLECTION.collect({id: 1, name: "jeff"});
// Doesn't cause rerender on Components
MY_COLLECTION.collect({id: 1, name: "jeff"}, {background: true});
Type | Default | Required |
---|---|---|
boolean | false | No |
select
If true
, a Selector is created for each collected data object.
MY_COLLECTION.collect({id: 1, name: "jeff"}, {select: true});
MY_COLLECTION.getSelector(1); // Returns Selector at '1'
These created Selectors can be identified with the same key used as primaryKey
in the collected data object.
Type | Default | Required |
---|---|---|
boolean | false | No |
UpdateConfig
The UpdateConfigInterface
is used as configuration object in functions like update()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface UpdateConfigInterface {
patch?: boolean | { addNewProperties?: boolean };
background?: boolean;
}
patch
If false
, the passed data object overwrites the entire found Item data instead of merging it into the Item data.
MY_COLLECTION.collect({id: 1, name: "jeff"});
MY_COLLECTION.update(1, {name: "hans"}, {patch: true});
MY_COLLECTION.getItemValue(1); // Returns '{id: 1, name: "hans"}'
MY_COLLECTION.update(1, {name: "frank"}, {patch: false});
MY_COLLECTION.getItemValue(1); // Returns '{name: "frank"}'
Keep in mind that if we decide to overwrite the entire Item data object,
we have to redefine the primaryKey
in the given data object.
Otherwise, the primary Key
gets missing, which can lead to problems.
Type | Default | Required |
---|---|---|
boolean | true | No |
background
When true
, the Item data object is updated in background
and won't cause any rerender on Components that have subscribed the Item or Collection.
// Causes rerender on Components
MY_COLLECTION.update(1, {name: "jeff"});
// Doesn't cause rerender on Components
MY_COLLECTION.update(1, {name: "frank"}, {background: true});
Type | Default | Required |
---|---|---|
boolean | false | No |
HasConfig
The HasConfigInterface
is used as configuration object in functions like hasGroup()
or hasSelector()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface HasConfigInterface {
notExisting?: boolean;
}
notExisting
When true
, also not officially existing Instances (like placeholder
) can be found.
// Returns placeholder Group
MY_COLLECTION.hasGroup('myPlaceholderGroup', {notExisting: true});
// Returns undefined
MY_COLLECTION.hasGroup('myPlaceholderGroup');
Type | Default | Required |
---|---|---|
boolean | false | No |
AddSideEffectConfig
The AddSideEffectConfigInterface
is used as configuration object in functions like addSideEffect()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface AddSideEffectConfigInterface {
weight?: number;
}
weight
Defines the weight
of the sideEffect
and thus when it is executed.
MY_STATE.addSideEffect('mySideEffect', (state, config) => {
// sideEffect callback
}, {weigth: 10});
The higher the weight
, the earlier the sideEffect
is performed.
Type | Default | Required |
---|---|---|
number | 10 | No |
GroupAddConfig
The GroupAddConfigInterface
is used as configuration object in functions like put()
or add()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface GroupAddConfig extends StateIngestConfigInterface {
method?: 'unshift' | 'push';
overwrite?: boolean;
}
Note: The GroupAddConfig
extends some other Interfaces:
method
Specifies the way of adding the collected data primaryKey/s
to the defined Group/s.
push
The primaryKey
is added to the end of the Group value array.
MY_COLLECTION.collect({id: 1, name: "jeff"}, [], {method: 'push'});
MY_COLLECTION.getGroup(MY_COLLECTION.config.defaultGroupKey).value; // Returns [5, 6, 0, 1]
unshift
The primaryKey
is added to the beginning of the Group value array.
MY_COLLECTION.collect({id: 8, name: "jeff"}, [], {method: 'unshift'});
MY_COLLECTION.getGroup(MY_COLLECTION.config.defaultGroupKey).value; // Returns [8, 5, 6, 0, 1]
Type | Default | Required |
---|---|---|
push' \| 'unshift' | 'push' | No |
overwrite
If true
, the position of the already existing itemKey
gets overwritten with the new position of the newly added same itemKey
.
const MY_GROUP = MY_COLLECTION.createGroup('group1', [1, 2, 5, 6]);
MY_GROUP.add(2, {overwrite: true}); // Group value is '[1, 5, 6, 2]'
MY_GROUP.add(5); // Group value is '[1, 5, 6, 2]'
Type | Default | Required |
---|---|---|
boolean | false | No |
UpdateItemKeyConfig
The UpdateItemKeyConfigInterface
is used as configuration object in functions like updateItemKey()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface UpdateItemKeyConfigInterface {
background?: boolean;
}
background
When true
, the itemKey
is updated in background
and won't cause any rerender on Components that have subscribed the Item or Collection.
// Causes rerender on Components
MY_COLLECTION.updateItemKey([1, 3]);
// Doesn't cause rerender on Components
MY_COLLECTION.updateItemKey([1, 3], {background: true});
Type | Default | Required |
---|---|---|
boolean | false | No |
ComputeConfig
The ComputeConfigInterface
is used as configuration object in functions like compute()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface ComputeConfigInterface {
autodetect?: boolean;
}
autodetect
Tells the Computed Class
to automatically detect the dependencies (Agile Sub Instances used in the computeFunction()
.
MY_COMPUTED.computeFunction = () => MY_NAME.value + MY_AGE.value;
MY_COMPUTED.recompute({autodetect: false});
MY_COMPUTED.deps; // Returns '[]'
MY_COMPUTED.recompute({autodetect: true});
MY_COMPUTED.deps; // Returns '[Obserrver(MY_NAME), Observer(MY_AGE)]'
Type | Default | Required |
---|---|---|
boolean | true | No |
RecomputeConfig
The RecomputeConfigInterface
is used as configuration object in functions like recompute()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface RecomputeConfigInterface
extends StateIngestConfigInterface,
ComputeConfigInterface {}
Note: The RecomputeConfig
extends some other Interfaces:
UpdateComputeFunctionConfig
The UpdateComputeFunctionConfigInterface
is used as configuration object in functions like updateComputeFunction()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
export interface UpdateComputeFunctionConfigInterface
extends RecomputeConfigInterface {
overwriteDeps?: boolean;
}
Note: The RecomputeConfig
extends some other Interfaces:
overwriteDeps
Whether the newly defined hard-coded dependencies are merged into the existing ones or overwrite them entirely.
MY_COMPUTED.deps; // // Returns '[Obserrver(MY_NAME), Observer(MY_AGE)]'
MY_COMPUTED.updateComputeFunction(() => {}, [MY_LOCATION], {overwriteDeps: false});
MY_COMPUTED.deps; // // Returns '[Obserrver(MY_NAME), Observer(MY_AGE), Observer(MY_LOCATION)]'
MY_COMPUTED.updateComputeFunction(() => {}, [MY_LOCATION], {overwriteDeps: true});
MY_COMPUTED.deps; // // Returns '[Observer(MY_LOCATION)]'
Type | Default | Required |
---|---|---|
boolean | true | No |
AgileHookConfigInterface
The AgileHookConfigInterface
is used as configuration object in functions like useAgile()
.
Here is a Typescript Interface for quick reference. However,
each property is explained in more detail below.
interface AgileHookConfigInterface {
key?: SubscriptionContainerKeyType;
agileInstance?: Agile;
proxyBased?: boolean;
selector?: SelectorMethodType;
componentId?: ComponentIdType;
observerType?: string;
deps?: any[];
}
key
The key/name
of the SubscriptionContainer that is created and added to the Observers.
useAgile(MY_STATE, {key: 'jeff'});
Such key can be very useful during debug sessions in order to analyse when which SubscriptionContainer triggered a rerender on a Component.
// Agile Debug: Registered Callback/Component based Subscription 'jeff', SubscriptionContainer('jeff')
// Agile Debug: Updated/Rerendered Subscriptions, [SubscriptionContainer('jeff'), ..]
// Agile Debug: Unregistered Callback/Component based Subscription 'jeff', SubscriptionContainer('jeff')
Type | Default | Required |
---|---|---|
string \| number | undefined | No |
agileInstance
The Agile Instance to which the created SubscriptionContainer belongs to.
However, since each Observer has an instance to the Agile Instance, useAgile()
can automatically derive the Agile Instance from that.
Type | Default | Required |
---|---|---|
Agile Instance | undefined | No |
proxyBased
warning
Requires an additional package called @agile-ts/proxytree
!
Whether to wrap a Proxy around the bound Agile Instance value object, to automatically constrain the way the selected Agile Instance is compared to determine whether the Component needs to be re-rendered based on the object's used properties.
useProxy(MY_STATE);
// equal to
useAgile(MY_STATE, {proxyBased: true});
Type | Default | Required |
---|---|---|
boolean | false | No |
selector
warning
Note that setting this property can destroy the useAgile type. -> should only be used internal!
useSelector(MY_STATE, (v.name) => v.name);
// equal to
useAgile(MY_STATE, {selector: (v.name) => v.name});
Equality comparison function that allows you to customize the way the selected Agile Instance is compared to determine whether the Component needs to be re-rendered.
Type | Default | Required |
---|---|---|
SelectorMethodType | undefined | No |
componentId
Key/Name identifier of the UI-Component the Subscription Container is bound to.
useAgile(MY_STATE, {componentId: 'User.tsx'});
In future re-render events
with the same componentId
are batched,
in addition to batching re-render events based on the SubscriptionContainer
.
Type | Default | Required |
---|---|---|
string\|number | undefined | No |
observerType
warning
Note that setting this property can destroy the useAgile type. -> should only be used internal!
useOutput(MY_STATE);
// equal to
useAgile(MY_STATE, {observerType: 'output'});
useValue(MY_STATE);
// equal to
useAgile(MY_STATE, {observerType: 'value'});
What type of Observer to be bound to the UI-Component.
Type | Default | Required |
---|---|---|
string | false | No |
deps
Dependencies that determine, in addition to unmounting and remounting the React-Component, when the specified Agile Sub Instances should be re-subscribed to the React-Component.
Related to github issue.
Type | Default | Required |
---|---|---|
any[] | [] | No |