function Promise.fromEvent(N,y)y=y or function()return true end return Promise._new(debug.traceback(nil,2),function(o,z,A)local Y local e=false local function G()Y:Disconnect()Y=nil end Y=N:Connect(function(...)local N=y(...)if N==true then o(...)if Y then G()else e=true end elseif type(N)~="\098\111\111\108\101\097\110"then error("\080\114\111\109\105\115\101\046\102\114\111\109\069\118\101\110\116 \112\114\101\100\105\099\097\116\101 \115\104\111\117\108\100 \097\108\119\097\121\115 \114\101\116\117\114\110 \097 \098\111\111\108\101\097\110")end end)if e and Y then return G()end A(function()G()end)end)end return Promise

function Promise.fromEvent(event, predicate)
	predicate = predicate or function()
		return true
	end

	return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel)
		local connection
		local shouldDisconnect = false

		local function disconnect()
			connection:Disconnect()
			connection = nil
		end

		-- We use shouldDisconnect because if the callback given to Connect is called before
		-- Connect returns, connection will still be nil. This happens with events that queue up
		-- events when there's nothing connected, such as RemoteEvents

		connection = event:Connect(function(...)
			local callbackValue = predicate(...)

			if callbackValue == true then
				resolve(...)

				if connection then
					disconnect()
				else
					shouldDisconnect = true
				end
			elseif type(callbackValue) ~= "boolean" then
				error("Promise.fromEvent predicate should always return a boolean")
			end
		end)

		if shouldDisconnect and connection then
			return disconnect()
		end

		onCancel(function()
			disconnect()
		end)
	end)
end

return Promise
