mirror of
https://github.com/littensy/charm.git
synced 2026-10-20 17:51:37 +00:00
chore: bump deps
This commit is contained in:
parent
28872264a2
commit
41d59cdfad
4 changed files with 58 additions and 94 deletions
|
|
@ -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
|
||||
|
|
|
|||
52
README.md
52
README.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue