-- Compiled with roblox-ts v2.0.2 --[[ * * Create a new Silo. * @param initialState initial state * @param modifiers modifier functions * @returns Silo ]] local function createSilo(initialState, modifiers) local state = table.freeze(table.clone(initialState)) local modifying = false local subscribers = {} local modifiersWithoutState = {} local notifySubscribers for name, modifier in pairs(modifiers) do modifiersWithoutState[name] = function(...) local args = { ... } if modifying then error("cannot call an action from within a modifier", 2) end modifying = true local oldState = state local newState = modifier(state, unpack(args)) if newState == oldState then modifying = false return nil end state = newState notifySubscribers(newState, oldState) modifying = false end end local getState = function() return state end local subscribe = function(subscriber) if modifying then error("cannot subscribe from within a modifier", 2) end local subscribed = true local _subscriber = subscriber table.insert(subscribers, _subscriber) return function() if not subscribed then return nil end if modifying then error("cannot unsubscribe from within a modifier", 2) end subscribed = false local _subscriber_1 = subscriber local index = (table.find(subscribers, _subscriber_1) or 0) - 1 if index == -1 then return nil end -- ▼ Array.unorderedRemove ▼ local _index = index + 1 local _length = #subscribers local _value = subscribers[_index] if _value ~= nil then subscribers[_index] = subscribers[_length] subscribers[_length] = nil end -- ▲ Array.unorderedRemove ▲ end end notifySubscribers = function(newState, oldState) for _, subscriber in subscribers do subscriber(newState, oldState) end end local observe = function(selector, observer, changed) local value = selector(getState()) observer(value) local didChange = changed or (function(newValue, oldValue) return newValue ~= oldValue end) return subscribe(function(newState) local newValue = selector(newState) if not didChange(newValue, value) then return nil end value = newValue observer(value) end) end local destroy = function() if modifying then error("cannot destroy silo from within a modifier", 2) end table.clear(subscribers) end return { initialState = table.freeze(table.clone(initialState)), actions = modifiersWithoutState, getState = getState, subscribe = subscribe, observe = observe, destroy = destroy, } end return { createSilo = createSilo, }