chore: bump deps

This commit is contained in:
littensy 2026-01-12 17:24:36 -08:00
parent 28872264a2
commit 41d59cdfad
4 changed files with 58 additions and 94 deletions

View file

@ -1,51 +1,7 @@
local fs = require("@std/fs")
local json = require("@std/json")
local net = require("@lute/net")
local process = require("@lute/process")
local CURRENT_FFLAGS = "https://clientsettingscdn.roblox.com/v1/settings/application?applicationName=PCStudioApp"
local FFLAG_KINDS = { "FFlag", "FInt" }
local function analyze()
local args = {
"luau-lsp",
"analyze",
"--sourcemap=sourcemap.json",
"--ignore=**/node_modules/**",
"--base-luaurc=.luaurc",
"--definitions=roblox.d.luau",
"--no-flags-enabled",
}
local response = net.request(CURRENT_FFLAGS, { method = "GET" })
local data: any = json.deserialize(response.body)
for name, value in data.applicationSettings do
if type(name) ~= "string" then
continue
end
for _, kind in FFLAG_KINDS do
if string.find(name, `^{kind}Luau`) then
table.insert(args, `--flag:{string.sub(name, #kind + 1)}={value}`)
end
end
end
table.insert(args, "packages")
table.insert(args, "tests")
table.insert(args, "benches")
local result = process.run(args)
local stderr = string.gsub(result.stderr, "Unknown FFlag[^\n]+\n", "")
print(stderr)
if result.exitcode == 1 then
process.exit(1)
end
end
process.run({ "rojo", "sourcemap", "--output=sourcemap.json" }, { stdio = "inherit" })
fs.writestringtofile(
@ -53,24 +9,26 @@ fs.writestringtofile(
net.request("https://luau-lsp.pages.dev/globalTypes.None.d.luau", { method = "GET" }).body
)
analyze()
-- process.run({
-- "luau-lsp",
-- "analyze",
-- "--sourcemap=sourcemap.json",
-- "--ignore=**/node_modules/**",
-- "--base-luaurc=.luaurc",
-- "--defs=roblox.d.luau",
-- "packages",
-- "tests",
-- "benches",
-- }, { stdio = "inherit" })
local analyze = process.run({
"luau-lsp",
"analyze",
"--sourcemap=sourcemap.json",
"--ignore=**/node_modules/**",
"--base-luaurc=.luaurc",
"--definitions=roblox.d.luau",
"packages",
"tests",
"benches",
}, { stdio = "inherit" })
fs.remove("roblox.d.luau")
process.run({ "selene", "packages", "tests", "benches" }, { stdio = "inherit" })
local selene = process.run({ "selene", "packages", "tests", "benches" }, { stdio = "inherit" })
process.run({ "stylua", "--check", "packages", "tests", "benches" }, { stdio = "inherit" })
local stylua = process.run({ "stylua", "--check", "packages", "tests", "benches" }, { stdio = "inherit" })
process.run({ "pnpm", "eslint", "packages" }, { stdio = "inherit" })
local eslint = process.run({ "pnpm", "eslint", "packages" }, { stdio = "inherit" })
if not (analyze.ok and selene.ok and stylua.ok and eslint.ok) then
process.exit(1)
end

View file

@ -233,10 +233,9 @@ Effects are fundamental to reactivity, allowing you to react to signal updates.
```luau
local getCounter, setCounter = signal(0)
-- Count is 0
effect(function()
print(`Count is {getCounter()}`)
end)
end) -- Count is 0
setCounter(1) -- Count is 1
```
@ -257,22 +256,33 @@ setCounter(1) -- Cleanup 0
dispose() -- Cleanup 1
```
Effects can be nested and they will clean up automatically when the parent effect re-runs or gets disposed. This means you don't have to manually clean up inner effects, and this applies to functions like `subscribe()` and `observe()`.
### Nested Effects
Effects can be nested inside other effects. When the outer effect re-runs, inner effects from the previous run are automatically cleaned up, and new inner effects are created if needed. The system ensures proper execution order; outer effects always run before their inner effects:
```luau
local getCounter, setCounter = signal(0)
local getShow, setShow = signal(true)
local getCount, setCount = signal(1)
effect(function()
print(`Outer: {getCounter()}`)
effect(function()
print(`Inner: {getcounter()}`)
end)
end)
if getShow() then
-- This inner effect is created when show() is true
effect(function()
print(`Count is: {getCount()}`)
end)
end
end) -- Output: Count is: 1
setCounter(1) -- Outer: 1, Inner: 1
setCounter(2) -- Outer: 2, Inner: 2
setCount(2) -- Count is: 2
-- When show becomes false, the inner effect is cleaned up
setShow(false) -- No output
setCount(3) -- No output (inner effect no longer exists)
```
Nested effect cleanup also applies to every reaction API (`subscribe()`, `listen()`, `observe()`) because they are built upon effects.
> [!NOTE]
> To run code that is "detached" from the parent effect or scope, use `untracked()` or a detached effect scope. If you suspect that the new nested effect behavior is causing issues with migration, try disabling the `flags.trackInnerEffects` flag to assist with debugging.
@ -289,17 +299,15 @@ local users, setUsers = reactive({
{ name = "John", surname = "Doe" },
})
-- Output: John Doe
effect(function()
print(`{users[1].name} {users[1].surname}`)
end)
end) -- Output: John Doe
-- Output: Jane Smith
setUsers(function(state)
state[1].name = "Jane"
state[1].surname = "Smith"
table.insert(state, { name = "Steve", surname = "Doe" })
end)
end) -- Output: Jane Smith
-- You can also mutate the reactive proxy directly:
users[1].name = "John" -- John Smith
@ -327,10 +335,9 @@ In case you want to opt-out of dependency tracking in an effect, you can use `un
local getTracked, setTracked = signal(0)
local getUntracked, setUntracked = signal(0)
-- Tracked: 0, Untracked: 0
effect(function()
print(`Tracked: {getTracked()}, Untracked: {untracked(getUntracked)}`)
end)
end) -- Output: Tracked: 0, Untracked: 0
setTracked(1) -- Tracked: 1, Untracked: 0
setUntracked(1) -- No output
@ -364,10 +371,9 @@ Similar to `untracked()`, but does not prevent the parent effect from tracking n
```luau
local getCounter, setCounter = signal(0)
-- Count is 0
local disposeOuter = effect(function()
print(`Count is {peek(getCounter)}`)
end)
end) -- Output: Count is 0
setCounter(1) -- No output; count was accessed in peek()
```
@ -430,7 +436,7 @@ The callback also receives the previous value, or `nil` when running for the fir
```luau
local getCounter, setCounter = signal(0)
-- Count is 0 (was nil)
-- Output: Count is 0 (was nil)
listen(getCounter, function(count, prevCount)
print(`Count is {count} (was {prevCount})`)
end)
@ -595,9 +601,7 @@ effect(function()
setCounter(function(count)
return math.min(count + 1, 3)
end)
end)
-- Output: 0, 1, 2, 3
end) -- Output: 0, 1, 2, 3
```
---
@ -931,7 +935,7 @@ This means nilable values may be replaced with `None` in patches, and code worki
Charm v0.11 introduces _a lot_ of breaking changes, so below are some tips that might help you migrate from an older version.
<details>
<summary><b>Terminology changes</b></summary>
<summary><b>Terminology</b></summary>
- Signal: A state container with one function to get the state, and another to update it
- Atom: A signal with the getter and setter combined into one function

View file

@ -191,7 +191,9 @@ local function runCleanups(cleanups: { () -> () })
for key, cleanup in cleanups do
cleanups[key] = nil
local prevSub = setActiveSub(nil)
xpcall(cleanup, warn or print)
xpcall(cleanup, function(err)
warn("Error occurred during effect cleanup:", debug.traceback(tostring(err), 2))
end)
activeSub = prevSub
end
end
@ -799,14 +801,14 @@ local function batch<Args..., Results...>(fn: (Args...) -> Results..., ...: Args
end
--[[
Converts a non-signal into a computed signal. If the function is already a
signal, it is returned as-is. Useful for memoizing a getter function
without creating unnecessary nested signals.
Wraps a function in a computed signal if it is not already a reactive
signal. Useful for memoizing a getter function without creating unnecessary
nested signals.
@param fn A signal or function that accesses signals
@return Computed signal if `fn` is not already a signal
@return `fn` wrapped in a computed signal if needed
]]
local function toSignal<T>(fn: () -> T): () -> T
local function toComputed<T>(fn: () -> T): () -> T
local name = debug.info(fn, "n")
return if name == "readSignal" or name == "readComputed" or name == "atomOper" then fn else computed(fn)
end
@ -825,7 +827,7 @@ end
@see https://github.com/littensy/charm?tab=readme-ov-file#listengetter-callback
]]
local function listen<T>(getter: () -> T, fn: (state: T, previous: T?) -> ()): () -> ()
local tracked = toSignal(getter)
local tracked = toComputed(getter)
local current: T
return effect(function()
@ -849,7 +851,7 @@ end
@see https://github.com/littensy/charm?tab=readme-ov-file#subscribegetter-callback
]]
local function subscribe<T>(getter: () -> T, fn: (state: T, lastState: T) -> ()): () -> ()
local tracked = toSignal(getter)
local tracked = toComputed(getter)
local current: T
local firstRun = true

View file

@ -3,5 +3,5 @@ wally = "UpliftGames/wally@0.3.2"
rojo = "rojo-rbx/rojo@7.6.1"
stylua = "johnnymorganz/stylua@2.3.1"
selene = "Kampfkarren/selene@0.29.0"
luau-lsp = "johnnymorganz/luau-lsp@1.57.1"
lute = "luau-lang/lute@0.1.0-nightly.20251213"
luau-lsp = "johnnymorganz/luau-lsp@1.60.0"
lute = "luau-lang/lute@0.1.0-nightly.20260112"