local g=require(script.Parent.Maid)local p=require(script.Parent.Signal)local J=require(script.Parent.Thread)local I={}I.__index=I function I.new(J,w)local k=setmetatable({},I)k._maid=g.new()k._shown=p.new(k._maid)k._shownMaid=g.new()k._maid:GiveTask(k._shownMaid)k.Instance=J:FindFirstChild(w)local function R()local g=k.Instance k._shown:Fire(g,k._shownMaid)k._shownMaid:GiveTask((g:GetPropertyChangedSignal("\080\097\114\101\110\116")):Connect(function()if not g.Parent then k._shownMaid:DoCleaning()end end))k._shownMaid:GiveTask(function()if k.Instance==g then k.Instance=nil end end)end local function K(g)if g.Name==w and not k.Instance then k.Instance=g R()end end k._maid:GiveTask(J.ChildAdded:Connect(K))if k.Instance then R()end return k end function I.Observe(p,g)if p.Instance then J.SpawnNow(g,p.Instance,p._shownMaid)end return p._shown:Connect(g)end function I.Destroy(g)g._maid:Destroy()end return I
--[[

	streamable = Streamable.new(parent: Instance, childName: string)

	streamable:Observe(handler: (child: Instance, maid: Maid) -> void): Connection
	streamable:Destroy()

--]]

local Maid = require(script.Parent.Maid)
local Signal = require(script.Parent.Signal)
local Thread = require(script.Parent.Thread)

local Streamable = {}
Streamable.__index = Streamable

function Streamable.new(parent, childName)
	local self = setmetatable({}, Streamable)

	self._maid = Maid.new()
	self._shown = Signal.new(self._maid)
	self._shownMaid = Maid.new()
	self._maid:GiveTask(self._shownMaid)

	self.Instance = parent:FindFirstChild(childName)

	local function OnInstanceSet()
		local instance = self.Instance
		self._shown:Fire(instance, self._shownMaid)
		self._shownMaid:GiveTask(instance:GetPropertyChangedSignal("Parent"):Connect(function()
			if not instance.Parent then
				self._shownMaid:DoCleaning()
			end
		end))
		self._shownMaid:GiveTask(function()
			if self.Instance == instance then
				self.Instance = nil
			end
		end)
	end

	local function OnChildAdded(child)
		if child.Name == childName and not self.Instance then
			self.Instance = child
			OnInstanceSet()
		end
	end

	self._maid:GiveTask(parent.ChildAdded:Connect(OnChildAdded))
	if self.Instance then
		OnInstanceSet()
	end

	return self
end

function Streamable:Observe(handler)
	if self.Instance then
		Thread.SpawnNow(handler, self.Instance, self._shownMaid)
	end
	return self._shown:Connect(handler)
end

function Streamable:Destroy()
	self._maid:Destroy()
end

return Streamable
