diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba48b1..3d5b4e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added -- `context()` +- `context()`. + +### Changed + +- `root()` now returns its destructor as the first value by default. ### Fixed diff --git a/docs/api/reactivity-core.md b/docs/api/reactivity-core.md index 93c2263..861e0e1 100644 --- a/docs/api/reactivity-core.md +++ b/docs/api/reactivity-core.md @@ -14,18 +14,15 @@ Creates and runs a function in a new stable scope. - **Type** ```lua - function root(fn: (destroy: () -> ()) -> T...): T... + function root(fn: (() -> ()) -> T...): (() -> (), T...) ``` - **Details** - Returns the result of the given function. + Returns a function to destroy the root scope. Also passes this function as + the first argument into its callback. - Creates a new stable scope, where creation of effects can be tracked and - properly disposed of. - - A function to destroy the root is passed into the callback, which will run - any cleanups and allow derived sources created to garbage collect. + All values returned by the callback are also returned following the destructor. ## source() diff --git a/docs/tut/advanced/nested-scoping.md b/docs/tut/advanced/nested-scoping.md index fb31c15..c5e6b4b 100644 --- a/docs/tut/advanced/nested-scoping.md +++ b/docs/tut/advanced/nested-scoping.md @@ -81,9 +81,8 @@ mount(function() effect(function() if toggled() then - local destroy = root(function(destroy) + local destroy = root(function() Counter() - return destroy end) cleanup(destroy) end diff --git a/docs/tut/crash-course/10-cleanup.md b/docs/tut/crash-course/10-cleanup.md index a863093..f6ca5f3 100644 --- a/docs/tut/crash-course/10-cleanup.md +++ b/docs/tut/crash-course/10-cleanup.md @@ -13,15 +13,13 @@ local effect = vide.effect local count = source(0) -local destroy = root(function(destroy) +local destroy = root(function() effect(function() local x = count() cleanup(function() print(x) end) end) cleanup(function() print "root destroyed" end) - - return destroy end) count(1) -- prints "0" diff --git a/docs/tut/crash-course/6-scope.md b/docs/tut/crash-course/6-scope.md index fa6ea8f..2853fff 100644 --- a/docs/tut/crash-course/6-scope.md +++ b/docs/tut/crash-course/6-scope.md @@ -43,21 +43,20 @@ local count = root(setup) -- ok since effect() was called within a stable scope count(1) -- prints "1" ``` -The scope created by `root()` can be destroyed by calling the function it passes -into the given function. +The scope created by `root()` can be destroyed. ```lua -local function setup(destroy) +local function setup() local count = source(0) effect(function() print(count()) end) - return count, destroy + return count end -local count, destroy = root(setup) +local destroy, count = root(setup) count(1) -- prints "1" diff --git a/src/mount.luau b/src/mount.luau index 315925e..b9d0ace 100644 --- a/src/mount.luau +++ b/src/mount.luau @@ -4,10 +4,9 @@ local root = require(script.Parent.root) local apply = require(script.Parent.apply) local function mount(component: () -> T, target: Instance?): () -> () - return root(function(destroy) + return root(function() local result = component() if target then apply(target, { result }) end - return destroy end) end diff --git a/src/root.luau b/src/root.luau index f8fc983..14bfa52 100644 --- a/src/root.luau +++ b/src/root.luau @@ -10,7 +10,7 @@ local destroy = graph.destroy local refs = {} -local function root(fn: (destroy: () -> ()) -> T...): T... +local function root(fn: (destroy: () -> ()) -> T...): (() -> (), T...) local node = create_node(false, false, false) refs[node] = true -- prevent gc of root node @@ -33,7 +33,7 @@ local function root(fn: (destroy: () -> ()) -> T...): T... throw(`error while running root():\n\n{result[2]}`) end - return unpack(result :: any, 2) + return destroy, unpack(result :: any, 2) end -return root :: ((fn: (destroy: () -> ()) -> T...) -> T...) & ((fn: (destroy: () -> ()) -> ()) -> ()) +return root :: (fn: (destroy: () -> ()) -> T...) -> (() -> (), T...) diff --git a/test/tests.luau b/test/tests.luau index 55642ff..3fbdbf4 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -892,7 +892,7 @@ TEST("create()", wrap_root(function() end do CASE "parent bound to source" - local wref, destroy = vide.root(function(destroy) + local _, wref, destroy = vide.root(function(destroy) local frame = create "Frame" { Name = "Parent" } local parent = source(frame :: Frame?) @@ -1228,7 +1228,7 @@ TEST("indexes()", wrap_root(function() local count = table.create(3, 0) - local output = vide.root(function() + local _, output = vide.root(function() local output = indexes(input, function(v, i) count[i] += 1 return v @@ -1690,7 +1690,7 @@ TEST("untrack()", wrap_root(function() local input = source(0) - local output, destroy = root(function(destroy) + local _, output, destroy = root(function(destroy) local output = derive(function() outer_count += 1 @@ -1820,7 +1820,7 @@ TEST("changed()", wrap_root(function() end do CASE "connection disconnected" - local text, destroy = root(function(destroy) + local _, text, destroy = root(function(destroy) local output = source(nil) return create "TextLabel" { @@ -2397,7 +2397,7 @@ TEST("graph edge cases", wrap_root(function() do CASE "do not destroy children" local parent = source(0) - local + local _, destroy, parent_to_destroy, update_parent_to_destroy @@ -2440,7 +2440,7 @@ TEST("graph edge cases", wrap_root(function() -- child B reevaluates due to already being queued -- parent destroys, destroys child B - uh oh - local + local _, destroy_parent, parent, update_parent @@ -2452,7 +2452,7 @@ TEST("graph edge cases", wrap_root(function() src end) - local destroy_child, _child_B = function() end, nil + local _, destroy_child, _child_B = nil, function() end, nil local count_A = 0