This commit is contained in:
aaron 2023-08-06 23:16:58 +01:00
parent e03082c941
commit fa2709f182
8 changed files with 367 additions and 216 deletions

View file

@ -32,100 +32,6 @@ Creates a new source state with the given value.
--------------------------------------------------------------------------------
## derive()
Derives a new state from existing states.
- ### Type
```lua
function derive<T>(source: () -> T): () -> T
```
- ### Details
The derived state will have its value recalculated when any source state it
derives from is updated.
Anytime its value is recalculated it is also cached, subsequent calls will
retun this cached value until it recalculates again.
Takes a callback that is immediately run to determine what states are being
referenced.
> ⚠️ Non-yielding.
- ### Example
```lua
local count = wrap(0)
local text = derive(function() return `count: {count()}` end)
text() -- "count: 0"
count(1)
text() -- "count: 1"
```
--------------------------------------------------------------------------------
## map()
Maps each value in a table state to a new table state.
- ### Type
```lua
function map<KI, VI, VO>(
source: () -> Map<KI, VI>,
transform: (value: () -> VI, index: KI) -> VO
): Map<KI, VO>
- ### Details
The transform function is called only ever *once* for each index in the
source table. The first argument is a state containing the index's value and
the second argument is just the index.
Anytime a new index is added, the transform function will be called again for
that new index.
Anytime an existing index changes, the transform function is not rerun,
instead the passed state for that index will update, causing anything
depending on it to update too.
Returns a state containing the mapped key-value pairs.
> ⚠️ Non-yielding.
- ### Example
```lua
type Item = {
name: string,
icon: number
}
local items = source {} :: () -> Array<Item>
local displays = map(numbers, function(item, i)
return ItemDisplay {
Name = function()
return item().name
end,
Image = function()
return "rbxassetid://" .. item().icon
end,
LayoutOrder = i
}
end)
```
--------------------------------------------------------------------------------
## watch()
Runs a callback on state change.
@ -166,3 +72,179 @@ Runs a callback on state change.
```
--------------------------------------------------------------------------------
## derive()
Derives a new state from existing states.
- ### Type
```lua
function derive<T>(source: () -> T): () -> T
```
- ### Details
The derived state will have its value recalculated when any source state it
derives from is updated.
Anytime its value is recalculated it is also cached, subsequent calls will
retun this cached value until it recalculates again.
Takes a callback that is immediately run to determine what states are being
referenced.
> ⚠️ Non-yielding.
- ### Example
```lua
local count = wrap(0)
local text = derive(function() return `count: {count()}` end)
text() -- "count: 0"
count(1)
text() -- "count: 1"
```
--------------------------------------------------------------------------------
## indexes()
Maps each index in a table to an object.
- ### Type
```lua
function indexes<KI, VI, VO>(
source: () -> Map<KI, VI>,
transform: (value: () -> VI, index: KI) -> VO
): Array<VO>
- ### Details
The transform function is called only ever *once* for each index in the
source table. The first argument is a state containing the index's value and
the second argument is just the index.
Anytime a new index is added, the transform function will be called again for
that new index.
Anytime an existing index value changes, the transform function is not rerun,
instead the passed state for that index will update, causing anything
depending on it to update too.
Returns a state containing an array of all objects returned by the transform.
> ⚠️ Non-yielding.
- ### Example
The intended purpose of this function is to map each index in a table to
a UI element.
```lua
type Item = {
name: string,
icon: number
}
local items = source {} :: () -> Array<Item>
local displays = indexes(numbers, function(item, i)
return ItemDisplay {
Name = function()
return item().name
end,
Image = function()
return "rbxassetid://" .. item().icon
end,
LayoutOrder = i
}
end)
```
--------------------------------------------------------------------------------
## values()
Maps each value in a table to an object.
- ### Type
```lua
function values<KI, VI, VO>(
source: () -> Map<KI, VI>,
transform: (value: VI, index: () -> KI) -> VO
): Array<VO>
- ### Details
The transform function is called only ever *once* for each value in the
source table. The first argument is the index's value and
the second argument is a state containing the index.
Anytime a new value is added, the transform function will be called again
for that new value.
Anytime an existing value's index changes, the transform function is not
rerun, instead the passed state for that value will update, causing anything
depending on it to update too.
Returns a state containing an array of all objects returned by the transform.
> ⚠️ Non-yielding.
- ### Example
The intended purpose of this function is to map each value in a table to
a UI element.
```lua
type Item = {
name: string,
icon: number
}
local items = source {} :: () -> Array<Item>
local displays = values(numbers, function(item, i)
return ItemDisplay {
Name = item.Name
Image = "rbxassetid://" .. item.icon,
LayoutOrder = i
}
end)
```
- ### Extra
When should you use `indexes()` and `values()`?
`values()` should be used when you have a fixed set of objects where the
same objects can be re-arranged in the source table. It maps a value to a
UI element.
e.g.
- List of all players.
- Inventory of items.
- Chat message history.
- Toast notifications.
`indexes()` should be used in other cases, especially when your source table
has primitive value. It maps an index to a UI element.
e.g.
- List of character or weapon stats.
In most cases, both functions will appear to have the same behavior.
The main difference is performance, picking the right function to use can
result in less property updates and less re-renders.
--------------------------------------------------------------------------------