Skip to main content

Stream

A push-based stream library for Roblox. A stream is just a function that, given a listener, starts pushing values into it and returns a CleanupTask representing the subscription.

local cleanup = Stream.fromSignal(workspace.ChildAdded)(function(child)
	print(child)
end)

Stream.clean(cleanup)

Most functions return either a Stream directly, or a function that takes a stream and returns a new stream (curried for piping).

Types

CleanupTask

type CleanupTask = any

A value representing work to be cleaned up. May be a function, thread, RBXScriptConnection, Instance, an object with a :Destroy() method, or an array of any of these.

Stream<T...>

type Stream<T...> = ((T...) → ()) → CleanupTask

A stream of values. Subscribing fires the listener zero or more times and returns the CleanupTask for the subscription.

LifeStream<T>

type LifeStream<T> = Stream<T,boolean>

A stream that emits values paired with a boolean indicating whether the value is alive (true) or dying (false).

Streamable<T>

type Streamable<T> = Stream<T> | ValueBase | RBXScriptSignal<T> | {Observe(self) → Stream<T>} | T

A value that can be converted to a Stream<T> via Stream.toStream. Accepts streams, ValueBase instances, RBXScriptSignals, tables with :Observe(), and plain values (which become a one-shot stream).

Functions

clean

Stream.clean(
cleanupCleanupTask,
refs{[any]true}?--

Internal cycle guard

) → ()

Cleans up a CleanupTask. Safely handles nil, functions, threads, connections, instances, objects with a :Destroy() method, and arrays thereof (in reverse order).

INFO

Tables with a metatable but no :Destroy() method will throw. Tables without a metatable are recursively cleaned and cleared.

NO_OP

Stream.NO_OP() → ()

A no-op listener. Useful when you want to start a stream but ignore its values.

never

Stream.never() → CleanupTask

A stream that never fires.

listen

Stream.listen(
streamStream<T...>,
listener((T...) → ())?
) → CleanupTask

Subscribes to a stream with an optional listener. If no listener is given, Stream.NO_OP is used.

listenTidy

Stream.listenTidy(
streamStream<T>,
tidyListener(T) → CleanupTask
) → CleanupTask

Subscribes to a stream such that each new value tears down the cleanup task returned by the previous listener invocation.

Stream.listenTidy(eachChild, function(child)
	return child.Touched:Connect(handle)
end)

from

Stream.from(array{T}) → Stream<T>

Constructs a stream that synchronously emits each value from array, then completes.

of

Stream.of(...T) → Stream<T>

Constructs a stream that synchronously emits each argument, then completes.

Stream.of(1, 2, 3)(print) --> 1, 2, 3

map

Stream.map(project(T...) → U...) → (Stream<T...>) → Stream<U...>

Maps one tuple to another.

Stream.pipe1(Stream.of(1, 2, 3), Stream.map(function(x)
	return x + 1
end))(print) --> 2, 3, 4

mapTo

Stream.mapTo(...U...) → (Stream<T...>) → Stream<U...>

Maps every emission to a fixed tuple.

tap

Stream.tap(callback(T...) → ()) → (Stream<T...>) → Stream<T...>

Taps into the stream and invokes callback for every emitted tuple. The original tuple is then passed through unchanged.

filter

Stream.filter(predicate(T...) → boolean) → (Stream<T...>) → Stream<T...>

Filters out values that do not pass predicate.

Stream.pipe1(Stream.of(1, 2, 3, 4, 5), Stream.filter(function(x)
	return x % 2 == 0
end))(print) --> 2, 4

delayed

Stream.delayed(secondsnumber) → (Stream<T...>) → Stream<T...>

Shifts the subscription forward by seconds using [task.delay].

merge

Stream.merge(...Stream<T...>) → Stream<T...>

Merges multiple streams into a single stream. The merged stream fires whenever any source fires.

pipe

Stream.pipe(
streamStream<...any>,
...(Stream<...any>) → Stream<...any>
) → Stream<...any>

Pipes a stream through a series of transformers.

Stream.pipe(source,
	Stream.map(function(x) return x + 1 end),
	Stream.filter(function(x) return x > 0 end))
TIP

Use Stream.pipe1 through Stream.pipe4 when you need typed inference; this dynamic variant erases types.

pipe0

Stream.pipe0(streamStream<A...>) → Stream<A...>

Strongly-typed variant of Stream.pipe that returns stream unchanged.

pipe1

Stream.pipe1(
streamStream<A...>,
t1(Stream<A...>) → Stream<Z...>
) → Stream<Z...>

Strongly-typed variant of Stream.pipe with one transformer.

pipe2

Stream.pipe2() → Stream<Z...>

Strongly-typed variant of Stream.pipe with two transformers.

pipe3

Stream.pipe3() → Stream<Z...>

Strongly-typed variant of Stream.pipe with three transformers.

pipe4

Stream.pipe4() → Stream<Z...>

Strongly-typed variant of Stream.pipe with four transformers.

race

Stream.race(...Stream<T...>) → Stream<T...>

Fires once with the first emission from any of the source streams, then unsubscribes from all of them.

skipUnchanged

Stream.skipUnchanged(streamStream<T>) → Stream<T>

Filters out consecutive duplicate values. Only emits when the value differs from the previously emitted one.

combineLatest

Stream.combineLatest(
streams{[K]Stream<V>},
skipCloneboolean?--

Skip the defensive [table.clone]

) → Stream<{[K]V}>

Combines a table of streams into a single stream that emits a snapshot table whenever any source fires, once every source has fired at least once.

Stream.combineLatest({
	health = playerHealth;
	name = playerName;
})(function(state)
	print(state.health, state.name)
end)
TIP

Note that the resulting stream will not emit until all input streams are emitted.

combine1

Stream.combine1(
aStream<A>,
project(A) → Z
) → Stream<Z>

Maps a single stream to a single value.

combine2

Stream.combine2(
aStream<A>,
bStream<B>,
project(
A,
B
) → Z
) → Stream<Z>

Combines two streams into one using project once both have fired.

combine3

Stream.combine3() → Stream<Z>

Combines three streams into one using project once all three have fired.

combine4

Stream.combine4() → Stream<Z>

Combines four streams into one using project once all four have fired.

switchAll

Stream.switchAll(streamStream<Stream<T...>>) → Stream<T...>

Flattens a stream of streams, subscribing only to the most recently emitted inner stream. When a new inner stream is emitted, the previous one is unsubscribed.

switchMap

Stream.switchMap(project(T...) → Stream<U...>) → (Stream<T...>) → Stream<U...>

Switches to a new stream from the current stream. Each outer value produces a new inner stream; the previous inner stream is unsubscribed.

Stream.pipe1(Stream.fromSignal(button.Activated), Stream.switchMap(function()
	return Stream.delayed(1)(Stream.of("clicked"))
end))(print)

nilOnce

Stream.nilOnce() → CleanupTask

A stream that fires once with nil, then completes.

replaceNil

Stream.replaceNil(valueT) → (Stream<T?>) → Stream<T>

Replaces every nil emission with value.

blockNil

Stream.blockNil(streamStream<T?>) → Stream<T>

Filters out nil emissions.

attributeOf

Stream.attributeOf(
instanceInstance,
attributeNamestring,
defaultany?--

optional fallback emitted when the attribute is nil

) → Stream<any?>

Observes an attribute on an instance. Fires immediately with the current value, then again on every change. If a default is provided, it is substituted whenever the attribute is nil.

toAttribute

Stream.toAttribute(attributeNamestring) → (Stream<Instance?>) → Stream<any?>

Switches the upstream instance to a stream of its attribute, or Stream.nilOnce if the instance is nil.

hasProperty

Stream.hasProperty(
instanceInstance,
propertyNamestring
) → boolean

Returns whether the instance has the named property.

propertyOf

Stream.propertyOf(
instanceInstance,
propertyNamestring
) → Stream<any>

Observes a property on an instance. Fires immediately with the current value, then again on every change.

CAUTION

If the property does not exist, this warns and returns Stream.never.

toProperty

Stream.toProperty(propertyNamestring) → (Stream<Instance?>) → Stream<any?>

Switches the upstream instance to a stream of its property, or Stream.nilOnce if the instance is nil.

fromSignal

Stream.fromSignal(eventRBXScriptSignal<T...>) → Stream<T...>

Converts an RBXScriptSignal into a stream.

fromSignalOnce

Stream.fromSignalOnce(eventRBXScriptSignal<T...>) → Stream<T...>

Same as Stream.fromSignal but uses :Once instead of :Connect.

fromValueBase

Stream.fromValueBase(valueBaseValueBase & {
ValueT,
}) → Stream<T>

Observes the Value of a ValueBase instance. Fires immediately with the current value, then again on every change.

listenTidyEach

Stream.listenTidyEach(
lifeStreamLifeStream<T>,
tidyListener(T) → CleanupTask
) → CleanupTask

Subscribes to a [LifeStream] such that each alive emission spawns a cleanup task that is torn down when that value dies.

Stream.listenTidyEach(Stream.eachPlayer, function(player)
	return player.CharacterAdded:Connect(handle)
end)

eachPlayer

Stream.eachPlayer(listener(
boolean
) → ()) → CleanupTask

A [LifeStream] of every player. Fires with (player, true) for each existing player and on PlayerAdded, and (player, false) on PlayerRemoving.

eachCharacter

Stream.eachCharacter(listener(
boolean
) → ()) → CleanupTask

A [LifeStream] of every player's character. Fires with (character, true) on CharacterAdded and (character, false) on CharacterRemoving, for every player past and present.

eachHumanoid

Stream.eachHumanoid(listener(
boolean
) → ()) → CleanupTask

A [LifeStream] of every player's humanoid. Tracks the Humanoid child of each Stream.eachCharacter character, re-emitting on [ChildAdded] and [ChildRemoved] within the character.

eachChildOf

Stream.eachChildOf(instanceInstance) → LifeStream<Instance>

A [LifeStream] of every child of instance. Fires with (child, true) for existing children and on ChildAdded, and (child, false) on ChildRemoved.

toEachChild

Stream.toEachChild(streamStream<Instance?>) → LifeStream<Instance>

Switches the upstream instance to its Stream.eachChildOf stream, or Stream.never when the upstream emits nil.

eachChildNamedOf

Stream.eachChildNamedOf(
instanceInstance,
namestring
) → LifeStream<Instance>

A [LifeStream] of children of instance filtered by name. A child becomes alive when its name matches name, and dies when it is renamed away or removed.

toEachChildNamed

Stream.toEachChildNamed(namestring) → (Stream<Instance?>) → LifeStream<Instance>

Switches the upstream instance to Stream.eachChildNamedOf with the given name.

firstChildOf

Stream.firstChildOf(
instanceInstance,
namestring,
classNameIsAstring?
) → Stream<Instance?>

Observes the first child of instance with name, optionally constrained by :IsA(classNameIsA). Emits nil when no matching child is present.

toFirstChild

Stream.toFirstChild(
namestring,
classNameIsAstring?
) → (Stream<Instance?>) → Stream<Instance?>

Switches the upstream instance to Stream.firstChildOf.

eachDescendantOf

Stream.eachDescendantOf(instanceInstance) → LifeStream<Instance>

A [LifeStream] of every descendant of instance. Fires with (descendant, true) for existing descendants and on DescendantAdded, and (descendant, false) on DescendantRemoving.

toEachDescendant

Stream.toEachDescendant(streamStream<Instance?>) → LifeStream<Instance>

Switches the upstream instance to its Stream.eachDescendantOf stream, or Stream.never when the upstream emits nil.

eachDescendantNamedOf

Stream.eachDescendantNamedOf(
instanceInstance,
namestring
) → LifeStream<Instance>

A [LifeStream] of descendants of instance filtered by name. A descendant becomes alive when its name matches name, and dies when it is renamed away or removed.

toEachDescendantNamed

Stream.toEachDescendantNamed(namestring) → (Stream<Instance?>) → LifeStream<Instance>

Switches the upstream instance to Stream.eachDescendantNamedOf with the given name.

firstDescendantOf

Stream.firstDescendantOf(
instanceInstance,
namestring,
classNameIsAstring?
) → Stream<Instance?>

Observes the first descendant of instance with name, optionally constrained by :IsA(classNameIsA). Emits nil when no matching descendant is present.

toFirstDescendant

Stream.toFirstDescendant(
namestring,
classNameIsAstring?
) → (Stream<Instance?>) → Stream<Instance?>

Switches the upstream instance to Stream.firstDescendantOf.

eachTagged

Stream.eachTagged(
tagNamestring,
ancestorInstance?
) → LifeStream<Instance>

A [LifeStream] of every instance tagged tagName, optionally limited to descendants of ancestor. Re-emits with false when an instance loses tag or descendant status.

tidyStream

Stream.tidyStream(streamStream<CleanupTask>) → Stream<CleanupTask>

Wraps a stream of cleanup tasks such that each emitted task is also tracked by the subscription's lifetime.

toHandler

Stream.toHandler(valueany) → ((...any) → ...any)?

Coerces a value into a handler function. Accepts functions, ValueBase instances (sets .Value), and tables with a :SetValue method. Returns nil if the value cannot be coerced.

fromNestedInstance

Stream.fromNestedInstance(valueInstance? | Streamable<Instance?>) → Stream<Instance?>

Resolves a possibly-nested instance container into a Stream<Instance?>. Accepts nil, Instance, ObjectValue (observes .Value), streams, and tables exposing :Observe().

toStream

Stream.toStream(stateStreamable<T>) → Stream<T>

Coerces a [Streamable] into a Stream<T>.

mount

Stream.mount(
instanceInstance,
props{[any]any}
) → {CleanupTask}

Mounts a props table onto an instance. Handles properties, events, parenting, and nested children. The contract is roughly:

  • String keys are assigned as properties; if the value is a stream, ValueBase, or function, the property is bound to it for the lifetime of the subscription.
  • String key "instance" invokes the value as a handler with the instance.
  • String key "cleanup" registers the value as a cleanup task.
  • Number keys are treated as implicit children; functions are resolved via Stream.fromNestedInstance, instances are parented, and tables are recursively mounted.
  • Function keys are invoked with instance to produce a sub-key.
  • Signal keys are connected to the value coerced via Stream.toHandler.
  • Parent is applied last and is allowed to be a stream.
Stream.mount(frame, {
	BackgroundTransparency = 1;
	[frame.MouseEnter] = function() print("hover") end;
	Stream.new "TextLabel" {
		Text = "Hi";
	};
})

new

Stream.new(classNamestring) → (props{[any]any}) → Stream<Instance>

Creates a new instance of className and returns a stream that, on subscription, mounts the props, fires the listener with the instance, and tears the instance down on cleanup.

Stream.new "ScreenGui" {
	Parent = playerGui;

	Stream.new "Frame" {
		Size = UDim2.fromScale(1, 1);
	};
}

newInstance

Stream.newInstance(classNamestring) → (props{[any]any}) → ()

Eager variant of Stream.new. Creates the instance immediately and returns it alongside its CleanupTask.

propertyOut

Stream.propertyOut(propertyNamestring) → (Instance) → Stream<any>

Returns a function that, given an instance, observes the named property.

compute

Stream.compute(...Streamable<any>...andafinal`(...) → any`combiner) → Stream<any>

Computes a derived stream from one or more [Streamable]s. The last argument is the combiner function; all preceding arguments are coerced via Stream.toStream and combined via Stream.combineLatest.

TIP

Prefer Stream.compute1 through Stream.compute4 when you need typed inference; this dynamic variant erases types.

compute1

Stream.compute1(
aStreamable<A>,
project(A) → Z
) → Stream<Z>

Strongly-typed variant of Stream.compute for a single source.

compute2

Stream.compute2() → Stream<Z>

Strongly-typed variant of Stream.compute for two sources.

compute3

Stream.compute3() → Stream<Z>

Strongly-typed variant of Stream.compute for three sources.

compute4

Stream.compute4() → Stream<Z>

Strongly-typed variant of Stream.compute for four sources.

Show raw api
{
    "functions": [
        {
            "name": "clean",
            "desc": "Cleans up a [CleanupTask]. Safely handles `nil`, functions, threads, connections, instances,\nobjects with a `:Destroy()` method, and arrays thereof (in reverse order).\n\n:::info\nTables with a metatable but no `:Destroy()` method will throw. Tables without a metatable are\nrecursively cleaned and cleared.\n:::",
            "params": [
                {
                    "name": "cleanup",
                    "desc": "",
                    "lua_type": "CleanupTask"
                },
                {
                    "name": "refs",
                    "desc": "Internal cycle guard",
                    "lua_type": "{ [any]: true }?"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 72,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "NO_OP",
            "desc": "A no-op listener. Useful when you want to start a stream but ignore its values.",
            "params": [],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 153,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "never",
            "desc": "A stream that never fires.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 163,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "listen",
            "desc": "Subscribes to a stream with an optional listener. If no listener is given, [Stream.NO_OP]\nis used.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<T...>"
                },
                {
                    "name": "listener",
                    "desc": "",
                    "lua_type": "((T...) -> ())?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 177,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "listenTidy",
            "desc": "Subscribes to a stream such that each new value tears down the cleanup task returned by\nthe previous listener invocation.\n\n```lua\nStream.listenTidy(eachChild, function(child)\n\treturn child.Touched:Connect(handle)\nend)\n```",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<T>"
                },
                {
                    "name": "tidyListener",
                    "desc": "",
                    "lua_type": "(T) -> CleanupTask"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 200,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "from",
            "desc": "Constructs a stream that synchronously emits each value from `array`, then completes.",
            "params": [
                {
                    "name": "array",
                    "desc": "",
                    "lua_type": "{ T }"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 226,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "of",
            "desc": "Constructs a stream that synchronously emits each argument, then completes.\n\n```lua\nStream.of(1, 2, 3)(print) --> 1, 2, 3\n```",
            "params": [
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "T"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 249,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "map",
            "desc": "Maps one tuple to another.\n\n```lua\nStream.pipe1(Stream.of(1, 2, 3), Stream.map(function(x)\n\treturn x + 1\nend))(print) --> 2, 3, 4\n```",
            "params": [
                {
                    "name": "project",
                    "desc": "",
                    "lua_type": "(T...) -> U..."
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<U...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 273,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "mapTo",
            "desc": "Maps every emission to a fixed tuple.",
            "params": [
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "U..."
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<U...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 293,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "tap",
            "desc": "Taps into the stream and invokes `callback` for every emitted tuple. The original tuple\nis then passed through unchanged.",
            "params": [
                {
                    "name": "callback",
                    "desc": "",
                    "lua_type": "(T...) -> ()"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 313,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "filter",
            "desc": "Filters out values that do not pass `predicate`.\n\n```lua\nStream.pipe1(Stream.of(1, 2, 3, 4, 5), Stream.filter(function(x)\n\treturn x % 2 == 0\nend))(print) --> 2, 4\n```",
            "params": [
                {
                    "name": "predicate",
                    "desc": "",
                    "lua_type": "(T...) -> boolean"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 340,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "delayed",
            "desc": "Shifts the subscription forward by `seconds` using [task.delay].",
            "params": [
                {
                    "name": "seconds",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 362,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "merge",
            "desc": "Merges multiple streams into a single stream. The merged stream fires whenever any source\nfires.",
            "params": [
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 381,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe",
            "desc": "Pipes a stream through a series of transformers.\n\n```lua\nStream.pipe(source,\n\tStream.map(function(x) return x + 1 end),\n\tStream.filter(function(x) return x > 0 end))\n```\n\n:::tip\nUse [Stream.pipe1] through [Stream.pipe4] when you need typed inference; this dynamic\nvariant erases types.\n:::",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<...any>"
                },
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "(Stream<...any>) -> Stream<...any>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<...any>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 412,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe0",
            "desc": "Strongly-typed variant of [Stream.pipe] that returns `stream` unchanged.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<A...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<A...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 427,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe1",
            "desc": "Strongly-typed variant of [Stream.pipe] with one transformer.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<A...>"
                },
                {
                    "name": "t1",
                    "desc": "",
                    "lua_type": "(Stream<A...>) -> Stream<Z...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 440,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe2",
            "desc": "Strongly-typed variant of [Stream.pipe] with two transformers.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 451,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe3",
            "desc": "Strongly-typed variant of [Stream.pipe] with three transformers.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 466,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "pipe4",
            "desc": "Strongly-typed variant of [Stream.pipe] with four transformers.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 482,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "race",
            "desc": "Fires once with the first emission from any of the source streams, then unsubscribes\nfrom all of them.",
            "params": [
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 501,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "skipUnchanged",
            "desc": "Filters out consecutive duplicate values. Only emits when the value differs from the\npreviously emitted one.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 533,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "combineLatest",
            "desc": "Combines a table of streams into a single stream that emits a snapshot table whenever any\nsource fires, once every source has fired at least once.\n\n```lua\nStream.combineLatest({\n\thealth = playerHealth;\n\tname = playerName;\n})(function(state)\n\tprint(state.health, state.name)\nend)\n```\n\n:::tip\nNote that the resulting stream will not emit until all input streams are emitted.\n:::",
            "params": [
                {
                    "name": "streams",
                    "desc": "",
                    "lua_type": "{ [K]: Stream<V> }"
                },
                {
                    "name": "skipClone",
                    "desc": "Skip the defensive [table.clone]",
                    "lua_type": "boolean?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<{ [K]: V }>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 568,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "combine1",
            "desc": "Maps a single stream to a single value.",
            "params": [
                {
                    "name": "a",
                    "desc": "",
                    "lua_type": "Stream<A>"
                },
                {
                    "name": "project",
                    "desc": "",
                    "lua_type": "(A) -> Z"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 653,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "combine2",
            "desc": "Combines two streams into one using `project` once both have fired.",
            "params": [
                {
                    "name": "a",
                    "desc": "",
                    "lua_type": "Stream<A>"
                },
                {
                    "name": "b",
                    "desc": "",
                    "lua_type": "Stream<B>"
                },
                {
                    "name": "project",
                    "desc": "",
                    "lua_type": "(A, B) -> Z"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 674,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "combine3",
            "desc": "Combines three streams into one using `project` once all three have fired.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 693,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "combine4",
            "desc": "Combines four streams into one using `project` once all four have fired.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 713,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "switchAll",
            "desc": "Flattens a stream of streams, subscribing only to the most recently emitted inner stream.\nWhen a new inner stream is emitted, the previous one is unsubscribed.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<Stream<T...>>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 736,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "switchMap",
            "desc": "Switches to a new stream from the current stream. Each outer value produces a new inner\nstream; the previous inner stream is unsubscribed.\n\n```lua\nStream.pipe1(Stream.fromSignal(button.Activated), Stream.switchMap(function()\n\treturn Stream.delayed(1)(Stream.of(\"clicked\"))\nend))(print)\n```",
            "params": [
                {
                    "name": "project",
                    "desc": "",
                    "lua_type": "(T...) -> Stream<U...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T...>) -> Stream<U...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 770,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "nilOnce",
            "desc": "A stream that fires once with `nil`, then completes.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 789,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "replaceNil",
            "desc": "Replaces every `nil` emission with `value`.",
            "params": [
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "T"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<T?>) -> Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 802,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "blockNil",
            "desc": "Filters out `nil` emissions.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<T?>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 824,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "attributeOf",
            "desc": "Observes an attribute on an instance. Fires immediately with the current value, then\nagain on every change. If a `default` is provided, it is substituted whenever the\nattribute is `nil`.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "attributeName",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "default",
                    "desc": "optional fallback emitted when the attribute is nil",
                    "lua_type": "any?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<any?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 848,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toAttribute",
            "desc": "Switches the upstream instance to a stream of its attribute, or [Stream.nilOnce] if the\ninstance is `nil`.",
            "params": [
                {
                    "name": "attributeName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> Stream<any?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 875,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "hasProperty",
            "desc": "Returns whether the instance has the named property.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "propertyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 896,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "propertyOf",
            "desc": "Observes a property on an instance. Fires immediately with the current value, then again\non every change.\n\n:::caution\nIf the property does not exist, this warns and returns [Stream.never].\n:::",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "propertyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<any>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 918,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toProperty",
            "desc": "Switches the upstream instance to a stream of its property, or [Stream.nilOnce] if the\ninstance is `nil`.",
            "params": [
                {
                    "name": "propertyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> Stream<any?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 949,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "fromSignal",
            "desc": "Converts an [RBXScriptSignal] into a stream.",
            "params": [
                {
                    "name": "event",
                    "desc": "",
                    "lua_type": "RBXScriptSignal<T...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 969,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "fromSignalOnce",
            "desc": "Same as [Stream.fromSignal] but uses `:Once` instead of `:Connect`.",
            "params": [
                {
                    "name": "event",
                    "desc": "",
                    "lua_type": "RBXScriptSignal<T...>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T...>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 985,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "fromValueBase",
            "desc": "Observes the `Value` of a [ValueBase] instance. Fires immediately with the current value,\nthen again on every change.",
            "params": [
                {
                    "name": "valueBase",
                    "desc": "",
                    "lua_type": "ValueBase & { Value: T, Changed: RBXScriptSignal }"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1002,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "listenTidyEach",
            "desc": "Subscribes to a [LifeStream] such that each alive emission spawns a cleanup task that is\ntorn down when that value dies.\n\n```lua\nStream.listenTidyEach(Stream.eachPlayer, function(player)\n\treturn player.CharacterAdded:Connect(handle)\nend)\n```",
            "params": [
                {
                    "name": "lifeStream",
                    "desc": "",
                    "lua_type": "LifeStream<T>"
                },
                {
                    "name": "tidyListener",
                    "desc": "",
                    "lua_type": "(T) -> CleanupTask"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1036,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachPlayer",
            "desc": "A [LifeStream] of every player. Fires with `(player, true)` for each existing player and\non `PlayerAdded`, and `(player, false)` on `PlayerRemoving`.",
            "params": [
                {
                    "name": "listener",
                    "desc": "",
                    "lua_type": "(Player, boolean) -> ()"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1071,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachCharacter",
            "desc": "A [LifeStream] of every player's character. Fires with `(character, true)` on\n`CharacterAdded` and `(character, false)` on `CharacterRemoving`, for every player past\nand present.",
            "params": [
                {
                    "name": "listener",
                    "desc": "",
                    "lua_type": "(Model, boolean) -> ()"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1096,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachHumanoid",
            "desc": "A [LifeStream] of every player's humanoid. Tracks the [Humanoid] child of each\n[Stream.eachCharacter] character, re-emitting on [ChildAdded] and [ChildRemoved] within\nthe character.",
            "params": [
                {
                    "name": "listener",
                    "desc": "",
                    "lua_type": "(Humanoid, boolean) -> ()"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "CleanupTask"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1123,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachChildOf",
            "desc": "A [LifeStream] of every child of `instance`. Fires with `(child, true)` for existing\nchildren and on `ChildAdded`, and `(child, false)` on `ChildRemoved`.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1157,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toEachChild",
            "desc": "Switches the upstream instance to its [Stream.eachChildOf] stream, or [Stream.never] when\nthe upstream emits `nil`.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<Instance?>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1183,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachChildNamedOf",
            "desc": "A [LifeStream] of children of `instance` filtered by name. A child becomes alive when its\nname matches `name`, and dies when it is renamed away or removed.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1201,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toEachChildNamed",
            "desc": "Switches the upstream instance to [Stream.eachChildNamedOf] with the given name.",
            "params": [
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1222,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "firstChildOf",
            "desc": "Observes the first child of `instance` with `name`, optionally constrained by\n`:IsA(classNameIsA)`. Emits `nil` when no matching child is present.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "classNameIsA",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Instance?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1241,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toFirstChild",
            "desc": "Switches the upstream instance to [Stream.firstChildOf].",
            "params": [
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "classNameIsA",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> Stream<Instance?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1269,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachDescendantOf",
            "desc": "A [LifeStream] of every descendant of `instance`. Fires with `(descendant, true)` for\nexisting descendants and on `DescendantAdded`, and `(descendant, false)` on\n`DescendantRemoving`.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1292,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toEachDescendant",
            "desc": "Switches the upstream instance to its [Stream.eachDescendantOf] stream, or [Stream.never]\nwhen the upstream emits `nil`.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<Instance?>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1318,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachDescendantNamedOf",
            "desc": "A [LifeStream] of descendants of `instance` filtered by name. A descendant becomes alive\nwhen its name matches `name`, and dies when it is renamed away or removed.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1336,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toEachDescendantNamed",
            "desc": "Switches the upstream instance to [Stream.eachDescendantNamedOf] with the given name.",
            "params": [
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1357,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "firstDescendantOf",
            "desc": "Observes the first descendant of `instance` with `name`, optionally constrained by\n`:IsA(classNameIsA)`. Emits `nil` when no matching descendant is present.",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "classNameIsA",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Instance?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1376,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toFirstDescendant",
            "desc": "Switches the upstream instance to [Stream.firstDescendantOf].",
            "params": [
                {
                    "name": "name",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "classNameIsA",
                    "desc": "",
                    "lua_type": "string?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Stream<Instance?>) -> Stream<Instance?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1404,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "eachTagged",
            "desc": "A [LifeStream] of every instance tagged `tagName`, optionally limited to descendants of\n`ancestor`. Re-emits with `false` when an instance loses tag or descendant status.",
            "params": [
                {
                    "name": "tagName",
                    "desc": "",
                    "lua_type": "string"
                },
                {
                    "name": "ancestor",
                    "desc": "",
                    "lua_type": "Instance?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "LifeStream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1427,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "tidyStream",
            "desc": "Wraps a stream of cleanup tasks such that each emitted task is also tracked by the\nsubscription's lifetime.",
            "params": [
                {
                    "name": "stream",
                    "desc": "",
                    "lua_type": "Stream<CleanupTask>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<CleanupTask>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1478,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toHandler",
            "desc": "Coerces a value into a handler function. Accepts functions, [ValueBase] instances (sets\n`.Value`), and tables with a `:SetValue` method. Returns `nil` if the value cannot be\ncoerced.",
            "params": [
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "any"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "((...any) -> ...any)?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1499,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "fromNestedInstance",
            "desc": "Resolves a possibly-nested instance container into a `Stream<Instance?>`. Accepts `nil`,\n[Instance], [ObjectValue] (observes `.Value`), streams, and tables exposing `:Observe()`.",
            "params": [
                {
                    "name": "value",
                    "desc": "",
                    "lua_type": "Instance? | Streamable<Instance?>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Instance?>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1524,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "toStream",
            "desc": "Coerces a [Streamable] into a `Stream<T>`.",
            "params": [
                {
                    "name": "state",
                    "desc": "",
                    "lua_type": "Streamable<T>"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<T>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1560,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "mount",
            "desc": "Mounts a props table onto an instance. Handles properties, events, parenting, and nested\nchildren. The contract is roughly:\n\n* String keys are assigned as properties; if the value is a stream, [ValueBase], or\n  function, the property is bound to it for the lifetime of the subscription.\n* String key `\"instance\"` invokes the value as a handler with the instance.\n* String key `\"cleanup\"` registers the value as a cleanup task.\n* Number keys are treated as implicit children; functions are resolved via\n  [Stream.fromNestedInstance], instances are parented, and tables are recursively mounted.\n* Function keys are invoked with `instance` to produce a sub-key.\n* Signal keys are connected to the value coerced via [Stream.toHandler].\n* `Parent` is applied last and is allowed to be a stream.\n\n```lua\nStream.mount(frame, {\n\tBackgroundTransparency = 1;\n\t[frame.MouseEnter] = function() print(\"hover\") end;\n\tStream.new \"TextLabel\" {\n\t\tText = \"Hi\";\n\t};\n})\n```",
            "params": [
                {
                    "name": "instance",
                    "desc": "",
                    "lua_type": "Instance"
                },
                {
                    "name": "props",
                    "desc": "",
                    "lua_type": "{ [any]: any }"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "{ CleanupTask }"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1604,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "new",
            "desc": "Creates a new instance of `className` and returns a stream that, on subscription, mounts\nthe props, fires the listener with the instance, and tears the instance down on cleanup.\n\n```lua\nStream.new \"ScreenGui\" {\n\tParent = playerGui;\n\n\tStream.new \"Frame\" {\n\t\tSize = UDim2.fromScale(1, 1);\n\t};\n}\n```",
            "params": [
                {
                    "name": "className",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(props: { [any]: any }) -> Stream<Instance>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1750,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "newInstance",
            "desc": "Eager variant of [Stream.new]. Creates the instance immediately and returns it alongside\nits [CleanupTask].",
            "params": [
                {
                    "name": "className",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(props: { [any]: any }) -> (Instance, CleanupTask)"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1772,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "propertyOut",
            "desc": "Returns a function that, given an instance, observes the named property.",
            "params": [
                {
                    "name": "propertyName",
                    "desc": "",
                    "lua_type": "string"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "(Instance) -> Stream<any>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1790,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "compute",
            "desc": "Computes a derived stream from one or more [Streamable]s. The last argument is the\ncombiner function; all preceding arguments are coerced via [Stream.toStream] and combined\nvia [Stream.combineLatest].\n\n:::tip\nPrefer [Stream.compute1] through [Stream.compute4] when you need typed inference; this\ndynamic variant erases types.\n:::",
            "params": [
                {
                    "name": "...",
                    "desc": "",
                    "lua_type": "Streamable<any>... and a final `(...) -> any` combiner"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<any>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1813,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "compute1",
            "desc": "Strongly-typed variant of [Stream.compute] for a single source.",
            "params": [
                {
                    "name": "a",
                    "desc": "",
                    "lua_type": "Streamable<A>"
                },
                {
                    "name": "project",
                    "desc": "",
                    "lua_type": "(A) -> Z"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1843,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "compute2",
            "desc": "Strongly-typed variant of [Stream.compute] for two sources.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1856,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "compute3",
            "desc": "Strongly-typed variant of [Stream.compute] for three sources.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1869,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "compute4",
            "desc": "Strongly-typed variant of [Stream.compute] for four sources.",
            "params": [],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Stream<Z>"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1882,
                "path": "packages/stream/src/Stream.luau"
            }
        }
    ],
    "properties": [],
    "types": [
        {
            "name": "CleanupTask",
            "desc": "A value representing work to be cleaned up. May be a function, thread, [RBXScriptConnection],\n[Instance], an object with a `:Destroy()` method, or an array of any of these.",
            "lua_type": "any",
            "source": {
                "line": 56,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "Stream<T...>",
            "desc": "A stream of values. Subscribing fires the listener zero or more times and returns the\n[CleanupTask] for the subscription.",
            "lua_type": "((T...) -> ()) -> CleanupTask",
            "source": {
                "line": 145,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "LifeStream<T>",
            "desc": "A stream that emits values paired with a boolean indicating whether the value is alive\n(`true`) or dying (`false`).",
            "lua_type": "Stream<T, boolean>",
            "source": {
                "line": 1018,
                "path": "packages/stream/src/Stream.luau"
            }
        },
        {
            "name": "Streamable<T>",
            "desc": "A value that can be converted to a `Stream<T>` via [Stream.toStream]. Accepts streams,\n[ValueBase] instances, [RBXScriptSignal]s, tables with `:Observe()`, and plain values\n(which become a one-shot stream).",
            "lua_type": "Stream<T> | ValueBase | RBXScriptSignal<T> | { Observe: (self) -> Stream<T> } | T",
            "source": {
                "line": 1550,
                "path": "packages/stream/src/Stream.luau"
            }
        }
    ],
    "name": "Stream",
    "desc": "A push-based stream library for Roblox. A stream is just a function that, given a listener,\nstarts pushing values into it and returns a [CleanupTask](#CleanupTask) representing the\nsubscription.\n\n```lua\nlocal cleanup = Stream.fromSignal(workspace.ChildAdded)(function(child)\n\tprint(child)\nend)\n\nStream.clean(cleanup)\n```\n\nMost functions return either a [Stream] directly, or a function that takes a stream and\nreturns a new stream (curried for piping).",
    "source": {
        "line": 43,
        "path": "packages/stream/src/Stream.luau"
    }
}