forked from littensy/reflex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreateSelectArrayDiffs.lua
69 lines (55 loc) · 1.86 KB
/
createSelectArrayDiffs.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
--!strict
local createSelector = require(script.Parent.Parent.createSelector)
type ArrayDiffs<K, V> = {
additions: { Entry<K, V> },
deletions: { Entry<K, V> },
}
type Entry<K, V> = {
key: K,
value: V,
id: unknown,
}
--[=[
Tracks the addition and removal of items in an array. Creates a selector that
returns an object containing the additions and deletions since the last update.
If your array contains immutable objects, you can use the `discriminator`
argument to return a unique identifier for each item. This prevents excessive
re-renders when an item is updated but not added or removed.
@param selector The selector to track.
@param discriminator A function that returns a unique identifier for each
item. Useful when tracking immutable objects.
@returns A selector that returns an object containing the additions and
deletions since the last update.
]=]
local function createSelectArrayDiffs<State, K, V>(
selector: (state: State) -> { [K]: V },
discriminator: ((item: V, index: K) -> unknown)?
): (state: State) -> ArrayDiffs<K, V>
local lastEntries: { [unknown]: Entry<K, V> } = {}
return createSelector(selector, function(items: { [K]: V })
local additions: { Entry<K, V> } = {}
local deletions: { Entry<K, V> } = {}
local entries: { [unknown]: Entry<K, V> } = {}
for key, item in items do
local id = if discriminator then discriminator(item, key) else item
local entry = { key = key, value = item, id = id }
assert(id ~= nil, "Discriminator returned a nil value")
if not lastEntries[id] then
table.insert(additions, entry)
end
entries[id] = entry
end
for id, item in lastEntries do
if not entries[id] then
local entry = lastEntries[id]
table.insert(deletions, entry)
end
end
lastEntries = entries
return {
additions = additions,
deletions = deletions,
}
end)
end
return createSelectArrayDiffs